mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
gst/videomixer/videomixer.c: Avoid divide by zero, choose masterpad as the pad with the highest framerate.
Original commit message from CVS: * gst/videomixer/videomixer.c: (gst_videomixer_pad_get_type), (gst_videomixer_pad_class_init), (gst_videomixer_pad_get_property), (gst_videomixer_pad_set_property), (gst_videomixer_pad_sinkconnect), (gst_videomixer_pad_init), (gst_video_mixer_background_get_type), (gst_videomixer_get_type), (gst_videomixer_class_init), (gst_videomixer_init), (gst_videomixer_request_new_pad), (gst_videomixer_blend_ayuv_i420), (pad_zorder_compare), (gst_videomixer_sort_pads), (gst_videomixer_fill_checker), (gst_videomixer_fill_color), (gst_videomixer_fill_queues), (gst_videomixer_blend_buffers), (gst_videomixer_update_queues), (gst_videomixer_loop), (plugin_init): Avoid divide by zero, choose masterpad as the pad with the highest framerate.
This commit is contained in:
parent
599383ccbc
commit
ecba04a8bc
2 changed files with 74 additions and 28 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2004-06-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/videomixer/videomixer.c: (gst_videomixer_pad_get_type),
|
||||||
|
(gst_videomixer_pad_class_init), (gst_videomixer_pad_get_property),
|
||||||
|
(gst_videomixer_pad_set_property),
|
||||||
|
(gst_videomixer_pad_sinkconnect), (gst_videomixer_pad_init),
|
||||||
|
(gst_video_mixer_background_get_type), (gst_videomixer_get_type),
|
||||||
|
(gst_videomixer_class_init), (gst_videomixer_init),
|
||||||
|
(gst_videomixer_request_new_pad), (gst_videomixer_blend_ayuv_i420),
|
||||||
|
(pad_zorder_compare), (gst_videomixer_sort_pads),
|
||||||
|
(gst_videomixer_fill_checker), (gst_videomixer_fill_color),
|
||||||
|
(gst_videomixer_fill_queues), (gst_videomixer_blend_buffers),
|
||||||
|
(gst_videomixer_update_queues), (gst_videomixer_loop),
|
||||||
|
(plugin_init):
|
||||||
|
Avoid divide by zero, choose masterpad as the pad with the highest
|
||||||
|
framerate.
|
||||||
|
|
||||||
2004-06-27 Julien Moutte <julien@moutte.net>
|
2004-06-27 Julien Moutte <julien@moutte.net>
|
||||||
|
|
||||||
* sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_decorate),
|
* sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_decorate),
|
||||||
|
|
|
@ -40,6 +40,21 @@ GST_DEBUG_CATEGORY_STATIC (gst_videomixer_debug);
|
||||||
typedef struct _GstVideoMixerPad GstVideoMixerPad;
|
typedef struct _GstVideoMixerPad GstVideoMixerPad;
|
||||||
typedef struct _GstVideoMixerPadClass GstVideoMixerPadClass;
|
typedef struct _GstVideoMixerPadClass GstVideoMixerPadClass;
|
||||||
|
|
||||||
|
#define GST_TYPE_VIDEO_MIXER (gst_videomixer_get_type())
|
||||||
|
#define GST_VIDEO_MIXER(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_MIXER, GstVideoMixer))
|
||||||
|
#define GST_VIDEO_MIXER_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEO_MIXER, GstVideoMixerClass))
|
||||||
|
#define GST_IS_VIDEO_MIXER(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_MIXER))
|
||||||
|
#define GST_IS_VIDEO_MIXER_CLASS(obj) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_MIXER))
|
||||||
|
|
||||||
|
static GType gst_videomixer_get_type (void);
|
||||||
|
|
||||||
|
typedef struct _GstVideoMixer GstVideoMixer;
|
||||||
|
typedef struct _GstVideoMixerClass GstVideoMixerClass;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -49,6 +64,8 @@ static void gst_videomixer_pad_get_property (GObject * object, guint prop_id,
|
||||||
static void gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
static void gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
static void gst_videomixer_sort_pads (GstVideoMixer * mix);
|
||||||
|
|
||||||
#define DEFAULT_PAD_ZORDER 0
|
#define DEFAULT_PAD_ZORDER 0
|
||||||
#define DEFAULT_PAD_XPOS 0
|
#define DEFAULT_PAD_XPOS 0
|
||||||
#define DEFAULT_PAD_YPOS 0
|
#define DEFAULT_PAD_YPOS 0
|
||||||
|
@ -86,7 +103,7 @@ struct _GstVideoMixerPadClass
|
||||||
GstRealPadClass parent_class;
|
GstRealPadClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType
|
static GType
|
||||||
gst_videomixer_pad_get_type (void)
|
gst_videomixer_pad_get_type (void)
|
||||||
{
|
{
|
||||||
static GType videomixer_pad_type = 0;
|
static GType videomixer_pad_type = 0;
|
||||||
|
@ -187,14 +204,17 @@ gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GstVideoMixerPad *pad;
|
GstVideoMixerPad *pad;
|
||||||
|
GstVideoMixer *mix;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_PAD (object));
|
g_return_if_fail (GST_IS_PAD (object));
|
||||||
|
|
||||||
pad = GST_VIDEO_MIXER_PAD (object);
|
pad = GST_VIDEO_MIXER_PAD (object);
|
||||||
|
mix = GST_VIDEO_MIXER (gst_pad_get_parent (GST_PAD (pad)));
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_PAD_ZORDER:
|
case ARG_PAD_ZORDER:
|
||||||
pad->zorder = g_value_get_uint (value);
|
pad->zorder = g_value_get_uint (value);
|
||||||
|
gst_videomixer_sort_pads (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);
|
||||||
|
@ -211,21 +231,6 @@ gst_videomixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GST_TYPE_VIDEO_MIXER (gst_videomixer_get_type())
|
|
||||||
#define GST_VIDEO_MIXER(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_MIXER, GstVideoMixer))
|
|
||||||
#define GST_VIDEO_MIXER_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEO_MIXER, GstVideoMixerClass))
|
|
||||||
#define GST_IS_VIDEO_MIXER(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_MIXER))
|
|
||||||
#define GST_IS_VIDEO_MIXER_CLASS(obj) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_MIXER))
|
|
||||||
|
|
||||||
typedef struct _GstVideoMixer GstVideoMixer;
|
|
||||||
typedef struct _GstVideoMixerClass GstVideoMixerClass;
|
|
||||||
|
|
||||||
GType gst_videomixer_get_type (void);
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
VIDEO_MIXER_BACKGROUND_CHECKER,
|
VIDEO_MIXER_BACKGROUND_CHECKER,
|
||||||
|
@ -284,7 +289,10 @@ gst_videomixer_pad_sinkconnect (GstPad * pad, const GstCaps * vscaps)
|
||||||
|
|
||||||
mix->in_width = MAX (mix->in_width, mixpad->in_width);
|
mix->in_width = MAX (mix->in_width, mixpad->in_width);
|
||||||
mix->in_height = MAX (mix->in_height, mixpad->in_height);
|
mix->in_height = MAX (mix->in_height, mixpad->in_height);
|
||||||
mix->in_framerate = mixpad->in_framerate;
|
if (mix->in_framerate < mixpad->in_framerate) {
|
||||||
|
mix->in_framerate = mixpad->in_framerate;
|
||||||
|
mix->master = mixpad;
|
||||||
|
}
|
||||||
|
|
||||||
return GST_PAD_LINK_OK;
|
return GST_PAD_LINK_OK;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +415,7 @@ static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
/*static guint gst_videomixer_signals[LAST_SIGNAL] = { 0 }; */
|
/*static guint gst_videomixer_signals[LAST_SIGNAL] = { 0 }; */
|
||||||
|
|
||||||
GType
|
static GType
|
||||||
gst_videomixer_get_type (void)
|
gst_videomixer_get_type (void)
|
||||||
{
|
{
|
||||||
static GType videomixer_type = 0;
|
static GType videomixer_type = 0;
|
||||||
|
@ -526,9 +534,6 @@ gst_videomixer_request_new_pad (GstElement * element,
|
||||||
|
|
||||||
mixpad->zorder = mix->numpads;
|
mixpad->zorder = mix->numpads;
|
||||||
mix->numpads++;
|
mix->numpads++;
|
||||||
if (mix->numpads == 1) {
|
|
||||||
mix->master = mixpad;
|
|
||||||
}
|
|
||||||
mix->sinkpads = g_slist_append (mix->sinkpads, newpad);
|
mix->sinkpads = g_slist_append (mix->sinkpads, newpad);
|
||||||
} else {
|
} else {
|
||||||
g_warning ("videomixer: this is not our template!\n");
|
g_warning ("videomixer: this is not our template!\n");
|
||||||
|
@ -578,8 +583,8 @@ gst_videomixer_handle_src_event (GstPad * pad, GstEvent * event)
|
||||||
V = ((V*mult) + (127*(32-mult)))>>5; \
|
V = ((V*mult) + (127*(32-mult)))>>5; \
|
||||||
Y = 255; \
|
Y = 255; \
|
||||||
} \
|
} \
|
||||||
U = MIN (U,255) \
|
U = MIN (U,255); \
|
||||||
V = MIN (V,255)
|
V = MIN (V,255);
|
||||||
|
|
||||||
#define BLEND_SUBTRACT(Y1,U1,V1,Y2,U2,V2,alpha,Y,U,V) \
|
#define BLEND_SUBTRACT(Y1,U1,V1,Y2,U2,V2,alpha,Y,U,V) \
|
||||||
Y = Y1-((Y2*alpha)>>8); \
|
Y = Y1-((Y2*alpha)>>8); \
|
||||||
|
@ -699,10 +704,11 @@ gst_videomixer_handle_src_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
#define BLEND_MODE BLEND_NORMAL
|
#define BLEND_MODE BLEND_NORMAL
|
||||||
#if 0
|
#if 0
|
||||||
|
#define BLEND_MODE BLEND_NORMAL
|
||||||
#define BLEND_MODE BLEND_ADD
|
#define BLEND_MODE BLEND_ADD
|
||||||
#define BLEND_MODE BLEND_SUBTRACT
|
#define BLEND_MODE BLEND_SUBTRACT
|
||||||
#define BLEND_MODE BLEND_DARKEN
|
|
||||||
#define BLEND_MODE BLEND_LIGHTEN
|
#define BLEND_MODE BLEND_LIGHTEN
|
||||||
|
#define BLEND_MODE BLEND_DARKEN
|
||||||
#define BLEND_MODE BLEND_MULTIPLY
|
#define BLEND_MODE BLEND_MULTIPLY
|
||||||
#define BLEND_MODE BLEND_DIFFERENCE
|
#define BLEND_MODE BLEND_DIFFERENCE
|
||||||
#define BLEND_MODE BLEND_EXCLUSION
|
#define BLEND_MODE BLEND_EXCLUSION
|
||||||
|
@ -814,6 +820,20 @@ gst_videomixer_blend_ayuv_i420 (guint8 * src, gint xpos, gint ypos,
|
||||||
|
|
||||||
#undef BLEND_MODE
|
#undef BLEND_MODE
|
||||||
|
|
||||||
|
static int
|
||||||
|
pad_zorder_compare (const GstVideoMixerPad * pad1,
|
||||||
|
const GstVideoMixerPad * pad2)
|
||||||
|
{
|
||||||
|
return pad1->zorder - pad2->zorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_videomixer_sort_pads (GstVideoMixer * mix)
|
||||||
|
{
|
||||||
|
mix->sinkpads = g_slist_sort (mix->sinkpads,
|
||||||
|
(GCompareFunc) pad_zorder_compare);
|
||||||
|
}
|
||||||
|
|
||||||
/* fill a buffer with a checkerboard pattern */
|
/* fill a buffer with a checkerboard pattern */
|
||||||
static void
|
static void
|
||||||
gst_videomixer_fill_checker (guint8 * dest, gint width, gint height)
|
gst_videomixer_fill_checker (guint8 * dest, gint width, gint height)
|
||||||
|
@ -895,8 +915,13 @@ gst_videomixer_fill_queues (GstVideoMixer * mix)
|
||||||
buffer = GST_BUFFER (data);
|
buffer = GST_BUFFER (data);
|
||||||
duration = GST_BUFFER_DURATION (buffer);
|
duration = GST_BUFFER_DURATION (buffer);
|
||||||
/* no duration on the buffer, use the framerate */
|
/* no duration on the buffer, use the framerate */
|
||||||
if (duration == -1)
|
if (duration == -1) {
|
||||||
duration = GST_SECOND / pad->in_framerate;
|
if (pad->in_framerate == 0.0) {
|
||||||
|
duration = G_MAXINT64;
|
||||||
|
} else {
|
||||||
|
duration = GST_SECOND / pad->in_framerate;
|
||||||
|
}
|
||||||
|
}
|
||||||
pad->queued += duration;
|
pad->queued += duration;
|
||||||
/* this buffer will need to be mixed */
|
/* this buffer will need to be mixed */
|
||||||
if (pad->queued > 0) {
|
if (pad->queued > 0) {
|
||||||
|
@ -951,7 +976,11 @@ gst_videomixer_update_queues (GstVideoMixer * mix)
|
||||||
|
|
||||||
interval = mix->master->queued;
|
interval = mix->master->queued;
|
||||||
if (interval <= 0) {
|
if (interval <= 0) {
|
||||||
interval = GST_SECOND / mix->in_framerate;
|
if (mix->in_framerate == 0.0) {
|
||||||
|
interval = G_MAXINT64;
|
||||||
|
} else {
|
||||||
|
interval = GST_SECOND / mix->in_framerate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
walk = mix->sinkpads;
|
walk = mix->sinkpads;
|
||||||
|
@ -1008,7 +1037,7 @@ gst_videomixer_loop (GstElement * element)
|
||||||
GST_STR_FOURCC ("I420"), "width", G_TYPE_INT, new_width, "height",
|
GST_STR_FOURCC ("I420"), "width", G_TYPE_INT, new_width, "height",
|
||||||
G_TYPE_INT, new_height, NULL);
|
G_TYPE_INT, new_height, NULL);
|
||||||
|
|
||||||
if (!gst_pad_try_set_caps (mix->srcpad, newcaps)) {
|
if (GST_PAD_LINK_FAILED (gst_pad_try_set_caps (mix->srcpad, newcaps))) {
|
||||||
GST_ELEMENT_ERROR (mix, CORE, NEGOTIATION, (NULL), (NULL));
|
GST_ELEMENT_ERROR (mix, CORE, NEGOTIATION, (NULL), (NULL));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue