mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
gst/videomixer/videomixer.c: Introduce some locking around the videomixer state so that it does not crash when adding...
Original commit message from CVS: Patch by: Sjoerd Simons <sjoerd at luon dot net> * gst/videomixer/videomixer.c: (gst_videomixer_pad_set_property), (gst_videomixer_set_master_geometry), (gst_videomixer_pad_sink_setcaps), (gst_videomixer_collect_free), (gst_videomixer_reset), (gst_videomixer_init), (gst_videomixer_finalize), (gst_videomixer_request_new_pad), (gst_videomixer_release_pad), (gst_videomixer_collected), (gst_videomixer_change_state): Introduce some locking around the videomixer state so that it does not crash when adding/removing pads. Fixes #383043.
This commit is contained in:
parent
40d3caa168
commit
e2f1b66fb2
2 changed files with 124 additions and 153 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2006-12-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
Patch by: Sjoerd Simons <sjoerd at luon dot net>
|
||||||
|
|
||||||
|
* gst/videomixer/videomixer.c: (gst_videomixer_pad_set_property),
|
||||||
|
(gst_videomixer_set_master_geometry),
|
||||||
|
(gst_videomixer_pad_sink_setcaps), (gst_videomixer_collect_free),
|
||||||
|
(gst_videomixer_reset), (gst_videomixer_init),
|
||||||
|
(gst_videomixer_finalize), (gst_videomixer_request_new_pad),
|
||||||
|
(gst_videomixer_release_pad), (gst_videomixer_collected),
|
||||||
|
(gst_videomixer_change_state):
|
||||||
|
Introduce some locking around the videomixer state so that it does not
|
||||||
|
crash when adding/removing pads. Fixes #383043.
|
||||||
|
|
||||||
2006-12-16 Tim-Philipp Müller <tim at centricular dot net>
|
2006-12-16 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -82,11 +82,73 @@ typedef struct _GstVideoMixerCollect GstVideoMixerCollect;
|
||||||
#define GST_IS_VIDEO_MIXER_CLASS(klass) \
|
#define GST_IS_VIDEO_MIXER_CLASS(klass) \
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_MIXER))
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_MIXER))
|
||||||
|
|
||||||
|
#define GST_VIDEO_MIXER_GET_STATE_LOCK(mix) \
|
||||||
|
(GST_VIDEO_MIXER(mix)->state_lock)
|
||||||
|
#define GST_VIDEO_MIXER_STATE_LOCK(mix) \
|
||||||
|
(g_mutex_lock(GST_VIDEO_MIXER_GET_STATE_LOCK (mix)))
|
||||||
|
#define GST_VIDEO_MIXER_STATE_UNLOCK(mix) \
|
||||||
|
(g_mutex_unlock(GST_VIDEO_MIXER_GET_STATE_LOCK (mix)))
|
||||||
|
|
||||||
static GType gst_videomixer_get_type (void);
|
static GType gst_videomixer_get_type (void);
|
||||||
|
|
||||||
typedef struct _GstVideoMixer GstVideoMixer;
|
typedef struct _GstVideoMixer GstVideoMixer;
|
||||||
typedef struct _GstVideoMixerClass GstVideoMixerClass;
|
typedef struct _GstVideoMixerClass GstVideoMixerClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVideoMixerBackground:
|
||||||
|
* @VIDEO_MIXER_BACKGROUND_CHECKER: checker pattern background
|
||||||
|
* @VIDEO_MIXER_BACKGROUND_BLACK: solid color black background
|
||||||
|
* @VIDEO_MIXER_BACKGROUND_WHITE: solid color white background
|
||||||
|
*
|
||||||
|
* The different backgrounds videomixer can blend over.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VIDEO_MIXER_BACKGROUND_CHECKER,
|
||||||
|
VIDEO_MIXER_BACKGROUND_BLACK,
|
||||||
|
VIDEO_MIXER_BACKGROUND_WHITE
|
||||||
|
}
|
||||||
|
GstVideoMixerBackground;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVideoMixer:
|
||||||
|
*
|
||||||
|
* The opaque #GstVideoMixer structure.
|
||||||
|
*/
|
||||||
|
struct _GstVideoMixer
|
||||||
|
{
|
||||||
|
GstElement element;
|
||||||
|
|
||||||
|
/* pad */
|
||||||
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
/* Lock to prevent the state to change while blending */
|
||||||
|
GMutex *state_lock;
|
||||||
|
/* Sink pads using Collect Pads from core's base library */
|
||||||
|
GstCollectPads *collect;
|
||||||
|
/* sinkpads, a GSList of GstVideoMixerPads */
|
||||||
|
GSList *sinkpads;
|
||||||
|
|
||||||
|
gint numpads;
|
||||||
|
|
||||||
|
/* the master pad */
|
||||||
|
GstVideoMixerPad *master;
|
||||||
|
|
||||||
|
gint in_width, in_height;
|
||||||
|
gint out_width, out_height;
|
||||||
|
gboolean setcaps;
|
||||||
|
|
||||||
|
GstVideoMixerBackground background;
|
||||||
|
|
||||||
|
gint fps_n;
|
||||||
|
gint fps_d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstVideoMixerClass
|
||||||
|
{
|
||||||
|
GstElementClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
static void gst_videomixer_pad_base_init (gpointer g_class);
|
static void gst_videomixer_pad_base_init (gpointer g_class);
|
||||||
static void gst_videomixer_pad_class_init (GstVideoMixerPadClass * klass);
|
static void gst_videomixer_pad_class_init (GstVideoMixerPadClass * klass);
|
||||||
static void gst_videomixer_pad_init (GstVideoMixerPad * mixerpad);
|
static void gst_videomixer_pad_init (GstVideoMixerPad * mixerpad);
|
||||||
|
@ -236,8 +298,10 @@ gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_PAD_ZORDER:
|
case ARG_PAD_ZORDER:
|
||||||
|
GST_VIDEO_MIXER_STATE_LOCK (mix);
|
||||||
pad->zorder = g_value_get_uint (value);
|
pad->zorder = g_value_get_uint (value);
|
||||||
gst_videomixer_sort_pads (mix);
|
gst_videomixer_sort_pads (mix);
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
break;
|
break;
|
||||||
case ARG_PAD_XPOS:
|
case ARG_PAD_XPOS:
|
||||||
pad->xpos = g_value_get_int (value);
|
pad->xpos = g_value_get_int (value);
|
||||||
|
@ -256,59 +320,6 @@ gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
gst_object_unref (mix);
|
gst_object_unref (mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVideoMixerBackground:
|
|
||||||
* @VIDEO_MIXER_BACKGROUND_CHECKER: checker pattern background
|
|
||||||
* @VIDEO_MIXER_BACKGROUND_BLACK: solid color black background
|
|
||||||
* @VIDEO_MIXER_BACKGROUND_WHITE: solid color white background
|
|
||||||
*
|
|
||||||
* The different backgrounds videomixer can blend over.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
VIDEO_MIXER_BACKGROUND_CHECKER,
|
|
||||||
VIDEO_MIXER_BACKGROUND_BLACK,
|
|
||||||
VIDEO_MIXER_BACKGROUND_WHITE
|
|
||||||
}
|
|
||||||
GstVideoMixerBackground;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVideoMixer:
|
|
||||||
*
|
|
||||||
* The opaque #GstVideoMixer structure.
|
|
||||||
*/
|
|
||||||
struct _GstVideoMixer
|
|
||||||
{
|
|
||||||
GstElement element;
|
|
||||||
|
|
||||||
/* pad */
|
|
||||||
GstPad *srcpad;
|
|
||||||
|
|
||||||
/* Sink pads using Collect Pads from core's base library */
|
|
||||||
GstCollectPads *collect;
|
|
||||||
/* sinkpads, a GSList of GstVideoMixerPads */
|
|
||||||
GSList *sinkpads;
|
|
||||||
|
|
||||||
gint numpads;
|
|
||||||
|
|
||||||
/* the master pad */
|
|
||||||
GstVideoMixerPad *master;
|
|
||||||
|
|
||||||
gint in_width, in_height;
|
|
||||||
gint out_width, out_height;
|
|
||||||
gboolean setcaps;
|
|
||||||
|
|
||||||
GstVideoMixerBackground background;
|
|
||||||
|
|
||||||
gint fps_n;
|
|
||||||
gint fps_d;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstVideoMixerClass
|
|
||||||
{
|
|
||||||
GstElementClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_videomixer_set_master_geometry (GstVideoMixer * mix)
|
gst_videomixer_set_master_geometry (GstVideoMixer * mix)
|
||||||
{
|
{
|
||||||
|
@ -376,6 +387,7 @@ gst_videomixer_pad_sink_setcaps (GstPad * pad, GstCaps * vscaps)
|
||||||
|| (framerate = gst_structure_get_value (structure, "framerate")) == NULL)
|
|| (framerate = gst_structure_get_value (structure, "framerate")) == NULL)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
|
GST_VIDEO_MIXER_STATE_LOCK (mix);
|
||||||
mixpad->fps_n = gst_value_get_fraction_numerator (framerate);
|
mixpad->fps_n = gst_value_get_fraction_numerator (framerate);
|
||||||
mixpad->fps_d = gst_value_get_fraction_denominator (framerate);
|
mixpad->fps_d = gst_value_get_fraction_denominator (framerate);
|
||||||
|
|
||||||
|
@ -383,6 +395,7 @@ gst_videomixer_pad_sink_setcaps (GstPad * pad, GstCaps * vscaps)
|
||||||
mixpad->in_height = in_height;
|
mixpad->in_height = in_height;
|
||||||
|
|
||||||
gst_videomixer_set_master_geometry (mix);
|
gst_videomixer_set_master_geometry (mix);
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
|
@ -573,12 +586,8 @@ gst_videomixer_class_init (GstVideoMixerClass * klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_videomixer_collect_free (GstCollectData * collect)
|
gst_videomixer_collect_free (GstVideoMixerCollect * mixcol)
|
||||||
{
|
{
|
||||||
GstVideoMixerCollect *mixcol;
|
|
||||||
|
|
||||||
mixcol = (GstVideoMixerCollect *) collect;
|
|
||||||
|
|
||||||
if (mixcol->buffer) {
|
if (mixcol->buffer) {
|
||||||
gst_buffer_unref (mixcol->buffer);
|
gst_buffer_unref (mixcol->buffer);
|
||||||
mixcol->buffer = NULL;
|
mixcol->buffer = NULL;
|
||||||
|
@ -600,7 +609,7 @@ gst_videomixer_reset (GstVideoMixer * mix)
|
||||||
/* clean up collect data */
|
/* clean up collect data */
|
||||||
walk = mix->collect->data;
|
walk = mix->collect->data;
|
||||||
while (walk) {
|
while (walk) {
|
||||||
GstCollectData *data = (GstCollectData *) walk->data;
|
GstVideoMixerCollect *data = (GstVideoMixerCollect *) walk->data;
|
||||||
|
|
||||||
gst_videomixer_collect_free (data);
|
gst_videomixer_collect_free (data);
|
||||||
walk = g_slist_next (walk);
|
walk = g_slist_next (walk);
|
||||||
|
@ -626,6 +635,7 @@ gst_videomixer_init (GstVideoMixer * mix)
|
||||||
(GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_videomixer_collected),
|
(GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_videomixer_collected),
|
||||||
mix);
|
mix);
|
||||||
|
|
||||||
|
mix->state_lock = g_mutex_new ();
|
||||||
/* initialize variables */
|
/* initialize variables */
|
||||||
gst_videomixer_reset (mix);
|
gst_videomixer_reset (mix);
|
||||||
|
|
||||||
|
@ -637,6 +647,7 @@ gst_videomixer_finalize (GObject * object)
|
||||||
GstVideoMixer *mix = GST_VIDEO_MIXER (object);
|
GstVideoMixer *mix = GST_VIDEO_MIXER (object);
|
||||||
|
|
||||||
gst_object_unref (mix->collect);
|
gst_object_unref (mix->collect);
|
||||||
|
g_mutex_free (mix->state_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -706,6 +717,7 @@ gst_videomixer_request_new_pad (GstElement * element,
|
||||||
templ->direction, "template", templ, NULL);
|
templ->direction, "template", templ, NULL);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
|
GST_VIDEO_MIXER_STATE_LOCK (mix);
|
||||||
mixpad->zorder = mix->numpads;
|
mixpad->zorder = mix->numpads;
|
||||||
mixpad->xpos = DEFAULT_PAD_XPOS;
|
mixpad->xpos = DEFAULT_PAD_XPOS;
|
||||||
mixpad->ypos = DEFAULT_PAD_YPOS;
|
mixpad->ypos = DEFAULT_PAD_YPOS;
|
||||||
|
@ -722,6 +734,7 @@ gst_videomixer_request_new_pad (GstElement * element,
|
||||||
/* Keep an internal list of mixpads for zordering */
|
/* Keep an internal list of mixpads for zordering */
|
||||||
mix->sinkpads = g_slist_append (mix->sinkpads, mixpad);
|
mix->sinkpads = g_slist_append (mix->sinkpads, mixpad);
|
||||||
mix->numpads++;
|
mix->numpads++;
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
} else {
|
} else {
|
||||||
g_warning ("videomixer: this is not our template!\n");
|
g_warning ("videomixer: this is not our template!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -738,31 +751,29 @@ static void
|
||||||
gst_videomixer_release_pad (GstElement * element, GstPad * pad)
|
gst_videomixer_release_pad (GstElement * element, GstPad * pad)
|
||||||
{
|
{
|
||||||
GstVideoMixer *mix = NULL;
|
GstVideoMixer *mix = NULL;
|
||||||
GSList *walk = NULL;
|
GstVideoMixerPad *mixpad;
|
||||||
|
|
||||||
mix = GST_VIDEO_MIXER (element);
|
mix = GST_VIDEO_MIXER (element);
|
||||||
|
GST_VIDEO_MIXER_STATE_LOCK (mix);
|
||||||
|
if (G_UNLIKELY (g_slist_find (mix->sinkpads, pad) == NULL)) {
|
||||||
|
g_warning ("Unknown pad %s", GST_PAD_NAME (pad));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
walk = mix->collect->data;
|
mixpad = GST_VIDEO_MIXER_PAD (pad);
|
||||||
while (walk) {
|
|
||||||
GstCollectData *data = (GstCollectData *) walk->data;
|
|
||||||
GstVideoMixerCollect *mixcol = (GstVideoMixerCollect *) data;
|
|
||||||
GstVideoMixerPad *mixpad = mixcol->mixpad;
|
|
||||||
|
|
||||||
walk = g_slist_next (walk);
|
|
||||||
|
|
||||||
if (mixpad == GST_VIDEO_MIXER_PAD (pad)) {
|
|
||||||
/* found it, remove from all sorts of lists */
|
|
||||||
mix->sinkpads = g_slist_remove (mix->sinkpads, pad);
|
mix->sinkpads = g_slist_remove (mix->sinkpads, pad);
|
||||||
gst_videomixer_collect_free (data);
|
gst_videomixer_collect_free (mixpad->mixcol);
|
||||||
gst_collect_pads_remove_pad (mix->collect, pad);
|
gst_collect_pads_remove_pad (mix->collect, pad);
|
||||||
gst_element_remove_pad (element, pad);
|
|
||||||
/* determine possibly new geometry and master */
|
/* determine possibly new geometry and master */
|
||||||
gst_videomixer_set_master_geometry (mix);
|
gst_videomixer_set_master_geometry (mix);
|
||||||
return;
|
mix->numpads--;
|
||||||
}
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
}
|
|
||||||
|
|
||||||
g_warning ("Unknown pad %s", GST_PAD_NAME (pad));
|
gst_element_remove_pad (element, pad);
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BLEND_NORMAL(Y1,U1,V1,Y2,U2,V2,alpha,Y,U,V) \
|
#define BLEND_NORMAL(Y1,U1,V1,Y2,U2,V2,alpha,Y,U,V) \
|
||||||
|
@ -1155,76 +1166,6 @@ gst_videomixer_update_queues (GstVideoMixer * mix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The basic idea is to get a buffer on all pads and mix them together.
|
|
||||||
* Based on the framerate, buffers are removed from the queues to make room
|
|
||||||
* for a new buffer.
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_videomixer_loop (GstElement * element)
|
|
||||||
{
|
|
||||||
GstVideoMixer *mix;
|
|
||||||
GstBuffer *outbuf;
|
|
||||||
gint outsize;
|
|
||||||
gint new_width, new_height;
|
|
||||||
gboolean eos;
|
|
||||||
|
|
||||||
mix = GST_VIDEO_MIXER (element);
|
|
||||||
|
|
||||||
eos = gst_videomixer_fill_queues (mix);
|
|
||||||
if (eos) {
|
|
||||||
gst_pad_push (mix->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
|
|
||||||
gst_element_set_eos (GST_ELEMENT (mix));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_width = mix->in_width;
|
|
||||||
new_height = mix->in_height;
|
|
||||||
|
|
||||||
if (new_width != mix->out_width ||
|
|
||||||
new_height != mix->out_height || !GST_PAD_CAPS (mix->srcpad)) {
|
|
||||||
GstCaps *newcaps;
|
|
||||||
|
|
||||||
newcaps = gst_caps_make_writable (
|
|
||||||
gst_pad_get_negotiated_caps (GST_PAD (mix->master)));
|
|
||||||
gst_caps_set_simple (newcaps, "format", GST_TYPE_FOURCC,
|
|
||||||
GST_STR_FOURCC ("AYUV"), "width", G_TYPE_INT, new_width, "height",
|
|
||||||
G_TYPE_INT, new_height, NULL);
|
|
||||||
|
|
||||||
if (GST_PAD_LINK_FAILED (gst_pad_try_set_caps (mix->srcpad, newcaps))) {
|
|
||||||
GST_ELEMENT_ERROR (mix, CORE, NEGOTIATION, (NULL), (NULL));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mix->out_width = new_width;
|
|
||||||
mix->out_height = new_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
outsize = ROUND_UP_2 (mix->out_width) * ROUND_UP_2 (mix->out_height) * 4;
|
|
||||||
|
|
||||||
outbuf = gst_pad_alloc_buffer_and_set_caps (mix->srcpad, GST_BUFFER_OFFSET_NONE, outsize);
|
|
||||||
switch (mix->background) {
|
|
||||||
case VIDEO_MIXER_BACKGROUND_CHECKER:
|
|
||||||
gst_videomixer_fill_checker (GST_BUFFER_DATA (outbuf),
|
|
||||||
new_width, new_height);
|
|
||||||
break;
|
|
||||||
case VIDEO_MIXER_BACKGROUND_BLACK:
|
|
||||||
gst_videomixer_fill_color (GST_BUFFER_DATA (outbuf),
|
|
||||||
new_width, new_height, 16, 128, 128);
|
|
||||||
break;
|
|
||||||
case VIDEO_MIXER_BACKGROUND_WHITE:
|
|
||||||
gst_videomixer_fill_color (GST_BUFFER_DATA (outbuf),
|
|
||||||
new_width, new_height, 240, 128, 128);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_videomixer_blend_buffers (mix, outbuf);
|
|
||||||
|
|
||||||
gst_videomixer_update_queues (mix);
|
|
||||||
|
|
||||||
gst_pad_push (mix->srcpad, GST_DATA (outbuf));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
||||||
{
|
{
|
||||||
|
@ -1236,6 +1177,7 @@ gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
||||||
g_return_val_if_fail (GST_IS_VIDEO_MIXER (mix), GST_FLOW_ERROR);
|
g_return_val_if_fail (GST_IS_VIDEO_MIXER (mix), GST_FLOW_ERROR);
|
||||||
|
|
||||||
GST_LOG ("all pads are collected");
|
GST_LOG ("all pads are collected");
|
||||||
|
GST_VIDEO_MIXER_STATE_LOCK (mix);
|
||||||
|
|
||||||
eos = gst_videomixer_fill_queues (mix);
|
eos = gst_videomixer_fill_queues (mix);
|
||||||
|
|
||||||
|
@ -1244,7 +1186,7 @@ gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
||||||
GST_LOG ("all our sinkpads are EOS, pushing downstream");
|
GST_LOG ("all our sinkpads are EOS, pushing downstream");
|
||||||
gst_pad_push_event (mix->srcpad, gst_event_new_eos ());
|
gst_pad_push_event (mix->srcpad, gst_event_new_eos ());
|
||||||
ret = GST_FLOW_WRONG_STATE;
|
ret = GST_FLOW_WRONG_STATE;
|
||||||
goto beach;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculating out buffer size from input size */
|
/* Calculating out buffer size from input size */
|
||||||
|
@ -1277,7 +1219,7 @@ gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
goto beach;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mix->background) {
|
switch (mix->background) {
|
||||||
|
@ -1298,11 +1240,19 @@ gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
|
||||||
gst_videomixer_blend_buffers (mix, outbuf);
|
gst_videomixer_blend_buffers (mix, outbuf);
|
||||||
|
|
||||||
gst_videomixer_update_queues (mix);
|
gst_videomixer_update_queues (mix);
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
|
|
||||||
ret = gst_pad_push (mix->srcpad, outbuf);
|
ret = gst_pad_push (mix->srcpad, outbuf);
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
error:
|
||||||
|
{
|
||||||
|
GST_VIDEO_MIXER_STATE_UNLOCK (mix);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1349,7 +1299,6 @@ gst_videomixer_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
gst_videomixer_reset (mix);
|
|
||||||
GST_LOG ("starting collectpads");
|
GST_LOG ("starting collectpads");
|
||||||
gst_collect_pads_start (mix->collect);
|
gst_collect_pads_start (mix->collect);
|
||||||
break;
|
break;
|
||||||
|
@ -1363,6 +1312,14 @@ gst_videomixer_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
|
||||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
gst_videomixer_reset (mix);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue