diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2004-06-28 07:28:49 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2004-06-28 07:28:49 +0000 |
commit | ecba04a8bc5a0921220948b6a1984b756098366d (patch) | |
tree | 5aca973d7cb5556b8bd74967782a200677ddf66d /gst/videomixer | |
parent | 599383ccbc25e9e25df53a0d84dbd4969c5d1fe1 (diff) |
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.
Diffstat (limited to 'gst/videomixer')
-rw-r--r-- | gst/videomixer/videomixer.c | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/gst/videomixer/videomixer.c b/gst/videomixer/videomixer.c index 5211ba1a..adcb6bcc 100644 --- a/gst/videomixer/videomixer.c +++ b/gst/videomixer/videomixer.c @@ -40,6 +40,21 @@ GST_DEBUG_CATEGORY_STATIC (gst_videomixer_debug); typedef struct _GstVideoMixerPad GstVideoMixerPad; 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_class_init (GstVideoMixerPadClass * klass); 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, const GValue * value, GParamSpec * pspec); +static void gst_videomixer_sort_pads (GstVideoMixer * mix); + #define DEFAULT_PAD_ZORDER 0 #define DEFAULT_PAD_XPOS 0 #define DEFAULT_PAD_YPOS 0 @@ -86,7 +103,7 @@ struct _GstVideoMixerPadClass GstRealPadClass parent_class; }; -GType +static GType gst_videomixer_pad_get_type (void) { 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) { GstVideoMixerPad *pad; + GstVideoMixer *mix; g_return_if_fail (GST_IS_PAD (object)); pad = GST_VIDEO_MIXER_PAD (object); + mix = GST_VIDEO_MIXER (gst_pad_get_parent (GST_PAD (pad))); switch (prop_id) { case ARG_PAD_ZORDER: pad->zorder = g_value_get_uint (value); + gst_videomixer_sort_pads (mix); break; case ARG_PAD_XPOS: 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 { 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_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; } @@ -407,7 +415,7 @@ static GstElementClass *parent_class = NULL; /*static guint gst_videomixer_signals[LAST_SIGNAL] = { 0 }; */ -GType +static GType gst_videomixer_get_type (void) { static GType videomixer_type = 0; @@ -526,9 +534,6 @@ gst_videomixer_request_new_pad (GstElement * element, mixpad->zorder = mix->numpads; mix->numpads++; - if (mix->numpads == 1) { - mix->master = mixpad; - } mix->sinkpads = g_slist_append (mix->sinkpads, newpad); } else { 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; \ Y = 255; \ } \ - U = MIN (U,255) \ - V = MIN (V,255) + U = MIN (U,255); \ + V = MIN (V,255); #define BLEND_SUBTRACT(Y1,U1,V1,Y2,U2,V2,alpha,Y,U,V) \ Y = Y1-((Y2*alpha)>>8); \ @@ -699,10 +704,11 @@ gst_videomixer_handle_src_event (GstPad * pad, GstEvent * event) #define BLEND_MODE BLEND_NORMAL #if 0 +#define BLEND_MODE BLEND_NORMAL #define BLEND_MODE BLEND_ADD #define BLEND_MODE BLEND_SUBTRACT -#define BLEND_MODE BLEND_DARKEN #define BLEND_MODE BLEND_LIGHTEN +#define BLEND_MODE BLEND_DARKEN #define BLEND_MODE BLEND_MULTIPLY #define BLEND_MODE BLEND_DIFFERENCE #define BLEND_MODE BLEND_EXCLUSION @@ -814,6 +820,20 @@ gst_videomixer_blend_ayuv_i420 (guint8 * src, gint xpos, gint ypos, #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 */ static void gst_videomixer_fill_checker (guint8 * dest, gint width, gint height) @@ -895,8 +915,13 @@ gst_videomixer_fill_queues (GstVideoMixer * mix) buffer = GST_BUFFER (data); duration = GST_BUFFER_DURATION (buffer); /* no duration on the buffer, use the framerate */ - if (duration == -1) - duration = GST_SECOND / pad->in_framerate; + if (duration == -1) { + if (pad->in_framerate == 0.0) { + duration = G_MAXINT64; + } else { + duration = GST_SECOND / pad->in_framerate; + } + } pad->queued += duration; /* this buffer will need to be mixed */ if (pad->queued > 0) { @@ -951,7 +976,11 @@ gst_videomixer_update_queues (GstVideoMixer * mix) interval = mix->master->queued; 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; @@ -1008,7 +1037,7 @@ gst_videomixer_loop (GstElement * element) GST_STR_FOURCC ("I420"), "width", G_TYPE_INT, new_width, "height", 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)); return; } |