summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/videomixer/videomixer2.c196
-rw-r--r--gst/videomixer/videomixer2.h7
-rw-r--r--gst/videomixer/videomixer2pad.h4
3 files changed, 83 insertions, 124 deletions
diff --git a/gst/videomixer/videomixer2.c b/gst/videomixer/videomixer2.c
index e72031d5f..a8e600217 100644
--- a/gst/videomixer/videomixer2.c
+++ b/gst/videomixer/videomixer2.c
@@ -107,32 +107,19 @@ GST_DEBUG_CATEGORY_STATIC (gst_videomixer2_debug);
#define GST_VIDEO_MIXER2_UNLOCK(mix) \
(g_mutex_unlock(GST_VIDEO_MIXER2_GET_LOCK (mix)))
+#define FORMATS " { AYUV, BGRA, ARGB, RGBA, ABGR, Y444, Y42B, YUY2, UYVY, "\
+ " YVYU, I420, YV12, Y41B, RGB, BGR, xRGB, xBGR, RGBx, BGRx } "
+
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_BGRA ";"
- GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_ABGR ";"
- GST_VIDEO_CAPS_YUV ("Y444") ";" GST_VIDEO_CAPS_YUV ("Y42B") ";"
- GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";"
- GST_VIDEO_CAPS_YUV ("YVYU") ";"
- GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") ";"
- GST_VIDEO_CAPS_YUV ("Y41B") ";" GST_VIDEO_CAPS_RGB ";"
- GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
- GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (FORMATS))
);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_BGRA ";"
- GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_ABGR ";"
- GST_VIDEO_CAPS_YUV ("Y444") ";" GST_VIDEO_CAPS_YUV ("Y42B") ";"
- GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";"
- GST_VIDEO_CAPS_YUV ("YVYU") ";"
- GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") ";"
- GST_VIDEO_CAPS_YUV ("Y41B") ";" GST_VIDEO_CAPS_RGB ";"
- GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
- GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (FORMATS))
);
static void gst_videomixer2_child_proxy_init (gpointer g_iface,
@@ -142,19 +129,6 @@ static gboolean gst_videomixer2_push_sink_event (GstVideoMixer2 * mix,
static void gst_videomixer2_release_pad (GstElement * element, GstPad * pad);
static void gst_videomixer2_reset_qos (GstVideoMixer2 * mix);
-static void
-_do_init (GType object_type)
-{
- static const GInterfaceInfo child_proxy_info = {
- (GInterfaceInitFunc) gst_videomixer2_child_proxy_init,
- NULL,
- NULL
- };
-
- g_type_add_interface_static (object_type, GST_TYPE_CHILD_PROXY,
- &child_proxy_info);
-}
-
struct _GstVideoMixer2Collect
{
GstCollectData2 collect; /* we extend the CollectData */
@@ -205,27 +179,34 @@ gst_videomixer2_update_src_caps (GstVideoMixer2 * mix)
for (l = mix->sinkpads; l; l = l->next) {
GstVideoMixer2Pad *mpad = l->data;
gint this_width, this_height;
+ gint fps_n, fps_d;
+ gint width, height;
+
+ fps_n = GST_VIDEO_INFO_FPS_N (&mpad->info);
+ fps_d = GST_VIDEO_INFO_FPS_D (&mpad->info);
+ width = GST_VIDEO_INFO_WIDTH (&mpad->info);
+ height = GST_VIDEO_INFO_HEIGHT (&mpad->info);
- if (mpad->fps_n == 0 || mpad->fps_d == 0 ||
- mpad->width == 0 || mpad->height == 0)
+ if (fps_n == 0 || fps_d == 0 || width == 0 || height == 0)
continue;
- this_width = mpad->width + MAX (mpad->xpos, 0);
- this_height = mpad->height + MAX (mpad->ypos, 0);
+ this_width = width + MAX (mpad->xpos, 0);
+ this_height = height + MAX (mpad->ypos, 0);
if (best_width < this_width)
best_width = this_width;
if (best_height < this_height)
best_height = this_height;
- if (mpad->fps_d == 0)
+ if (fps_d == 0)
cur_fps = 0.0;
else
- gst_util_fraction_to_double (mpad->fps_n, mpad->fps_d, &cur_fps);
+ gst_util_fraction_to_double (fps_n, fps_d, &cur_fps);
+
if (best_fps < cur_fps) {
best_fps = cur_fps;
- best_fps_n = mpad->fps_n;
- best_fps_d = mpad->fps_d;
+ best_fps_n = fps_n;
+ best_fps_d = fps_d;
}
}
@@ -238,19 +219,25 @@ gst_videomixer2_update_src_caps (GstVideoMixer2 * mix)
if (best_width > 0 && best_height > 0 && best_fps > 0) {
GstCaps *caps, *peercaps;
GstStructure *s;
+ GstVideoInfo info;
- if (mix->fps_n != best_fps_n || mix->fps_d != best_fps_d) {
- if (mix->segment.last_stop != -1) {
- mix->ts_offset = mix->segment.last_stop - mix->segment.start;
+ if (GST_VIDEO_INFO_FPS_N (&mix->info) != best_fps_n ||
+ GST_VIDEO_INFO_FPS_D (&mix->info) != best_fps_d) {
+ if (mix->segment.position != -1) {
+ mix->ts_offset = mix->segment.position - mix->segment.start;
mix->nframes = 0;
}
}
+ gst_video_info_set_format (&info, GST_VIDEO_INFO_FORMAT (&mix->info),
+ best_width, best_height);
+ info.fps_n = best_fps_n;
+ info.fps_d = best_fps_d;
+ info.par_n = GST_VIDEO_INFO_PAR_N (&mix->info);
+ info.par_d = GST_VIDEO_INFO_PAR_D (&mix->info);
- caps = gst_video_format_new_caps (mix->format,
- best_width, best_height, best_fps_n, best_fps_d,
- mix->par_n, mix->par_d);
+ caps = gst_video_info_to_caps (&info);
- peercaps = gst_pad_peer_get_caps (mix->srcpad);
+ peercaps = gst_pad_peer_query_caps (mix->srcpad, NULL);
if (peercaps) {
GstCaps *tmp;
@@ -281,10 +268,7 @@ gst_videomixer2_update_src_caps (GstVideoMixer2 * mix)
gst_structure_get_fraction (s, "fraction", &best_fps_n, &best_fps_d);
}
- mix->fps_n = best_fps_n;
- mix->fps_d = best_fps_d;
- mix->width = best_width;
- mix->height = best_height;
+ mix->info = info;
GST_VIDEO_MIXER2_UNLOCK (mix);
ret = gst_pad_set_caps (mix->srcpad, caps);
@@ -303,47 +287,32 @@ gst_videomixer2_pad_sink_setcaps (GstPad * pad, GstCaps * caps)
{
GstVideoMixer2 *mix;
GstVideoMixer2Pad *mixpad;
- GstVideoFormat fmt;
- gint width, height;
- gint fps_n = 0, fps_d = 0;
- gint par_n = 1, par_d = 1;
+ GstVideoInfo info;
gboolean ret = FALSE;
- GstStructure *s;
GST_INFO_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, caps);
mix = GST_VIDEO_MIXER2 (gst_pad_get_parent (pad));
mixpad = GST_VIDEO_MIXER2_PAD (pad);
- if (!gst_video_format_parse_caps (caps, &fmt, &width, &height) ||
- !gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d)) {
- GST_ERROR_OBJECT (pad, "Failed to parse caps");
- goto beach;
- }
-
- s = gst_caps_get_structure (caps, 0);
- if (gst_structure_has_field (s, "framerate")
- && !gst_video_parse_caps_framerate (caps, &fps_n, &fps_d)) {
+ if (gst_video_info_from_caps (&info, caps)) {
GST_ERROR_OBJECT (pad, "Failed to parse caps");
goto beach;
}
GST_VIDEO_MIXER2_LOCK (mix);
- if (mix->format != GST_VIDEO_FORMAT_UNKNOWN) {
- if (mix->format != fmt || mix->par_n != par_n || mix->par_d != par_d) {
+ if (GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_FORMAT_UNKNOWN) {
+ if (GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_INFO_FORMAT (&info) ||
+ GST_VIDEO_INFO_PAR_N (&mix->info) != GST_VIDEO_INFO_PAR_N (&info) ||
+ GST_VIDEO_INFO_PAR_D (&mix->info) != GST_VIDEO_INFO_PAR_D (&info)) {
GST_ERROR_OBJECT (pad, "Caps not compatible with other pads' caps");
GST_VIDEO_MIXER2_UNLOCK (mix);
goto beach;
}
}
- mix->format = fmt;
- mix->par_n = par_n;
- mix->par_d = par_d;
- mixpad->fps_n = fps_n;
- mixpad->fps_d = fps_d;
- mixpad->width = width;
- mixpad->height = height;
+ mix->info = info;
+ mixpad->info = info;
GST_VIDEO_MIXER2_UNLOCK (mix);
@@ -365,7 +334,7 @@ gst_videomixer2_pad_sink_getcaps (GstPad * pad)
mix = GST_VIDEO_MIXER2 (gst_pad_get_parent (pad));
- srccaps = gst_pad_get_fixed_caps_func (GST_PAD (mix->srcpad));
+ srccaps = gst_pad_get_current_caps (GST_PAD (mix->srcpad));
srccaps = gst_caps_make_writable (srccaps);
n = gst_caps_get_size (srccaps);
@@ -381,6 +350,8 @@ gst_videomixer2_pad_sink_getcaps (GstPad * pad)
GST_DEBUG_OBJECT (pad, "Returning %" GST_PTR_FORMAT, srccaps);
+ gst_object_unref (mix);
+
return srccaps;
}
@@ -396,7 +367,7 @@ gst_videomixer2_pad_sink_acceptcaps (GstPad * pad, GstCaps * caps)
mix = GST_VIDEO_MIXER2 (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (pad, "%" GST_PTR_FORMAT, caps);
- accepted_caps = gst_pad_get_fixed_caps_func (GST_PAD (mix->srcpad));
+ accepted_caps = gst_pad_get_current_caps (GST_PAD (mix->srcpad));
accepted_caps = gst_caps_make_writable (accepted_caps);
GST_LOG_OBJECT (pad, "src caps %" GST_PTR_FORMAT, accepted_caps);
@@ -561,9 +532,10 @@ gst_videomixer2_background_get_type (void)
return video_mixer_background_type;
}
-
-GST_BOILERPLATE_FULL (GstVideoMixer2, gst_videomixer2, GstElement,
- GST_TYPE_ELEMENT, _do_init);
+#define gst_videomixer2_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVideoMixer2, gst_videomixer2, GST_TYPE_ELEMENT,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
+ gst_videomixer2_child_proxy_init));
static void
gst_videomixer2_update_qos (GstVideoMixer2 * mix, gdouble proportion,
@@ -580,7 +552,7 @@ gst_videomixer2_update_qos (GstVideoMixer2 * mix, gdouble proportion,
if (G_UNLIKELY (diff > 0))
mix->earliest_time =
timestamp + 2 * diff + gst_util_uint64_scale_int (GST_SECOND,
- mix->fps_d, mix->fps_n);
+ GST_VIDEO_INFO_FPS_D (&mix->info), GST_VIDEO_INFO_FPS_N (&mix->info));
else
mix->earliest_time = timestamp + diff;
} else {
@@ -619,7 +591,7 @@ gst_videomixer2_reset (GstVideoMixer2 * mix)
mix->nframes = 0;
gst_segment_init (&mix->segment, GST_FORMAT_TIME);
- mix->segment.last_stop = -1;
+ mix->segment.position = -1;
gst_videomixer2_reset_qos (mix);
@@ -743,9 +715,9 @@ gst_videomixer2_fill_queues (GstVideoMixer2 * mix,
g_assert (start_time != -1 && end_time != -1);
/* Convert to the output segment rate */
- if (mix->segment.abs_rate != 1.0) {
- start_time *= mix->segment.abs_rate;
- end_time *= mix->segment.abs_rate;
+ if (ABS (mix->segment.rate) != 1.0) {
+ start_time *= ABS (mix->segment.rate);
+ end_time *= ABS (mix->segment.rate);
}
if (end_time >= output_start_time && start_time < output_end_time) {
@@ -952,10 +924,10 @@ gst_videomixer2_collected (GstCollectPads2 * pads, GstVideoMixer2 * mix)
mix->newseg_pending = FALSE;
}
- if (mix->segment.last_stop == -1)
+ if (mix->segment.position == -1)
output_start_time = mix->segment.start;
else
- output_start_time = mix->segment.last_stop;
+ output_start_time = mix->segment.position;
if (output_start_time >= mix->segment.stop) {
GST_DEBUG_OBJECT (mix, "Segment done");
@@ -1013,7 +985,7 @@ gst_videomixer2_collected (GstCollectPads2 * pads, GstVideoMixer2 * mix)
ret = GST_FLOW_OK;
}
- gst_segment_set_last_stop (&mix->segment, GST_FORMAT_TIME, output_end_time);
+ mix->segment.position = output_end_time;
mix->nframes++;
GST_VIDEO_MIXER2_UNLOCK (mix);
@@ -1233,7 +1205,7 @@ gst_videomixer2_src_query (GstPad * pad, GstQuery * query)
case GST_FORMAT_TIME:
gst_query_set_position (query, format,
gst_segment_to_stream_time (&mix->segment, GST_FORMAT_TIME,
- mix->segment.last_stop));
+ mix->segment.position));
res = TRUE;
break;
default:
@@ -1328,10 +1300,10 @@ gst_videomixer2_src_event (GstPad * pad, GstEvent * event)
}
/* Convert to the output segment rate */
- if (mix->segment.abs_rate != abs_rate) {
- if (mix->segment.abs_rate != 1.0 && p->mixcol->buffer) {
- p->mixcol->start_time /= mix->segment.abs_rate;
- p->mixcol->end_time /= mix->segment.abs_rate;
+ if (ABS (mix->segment.rate) != abs_rate) {
+ if (ABS (mix->segment.rate) != 1.0 && p->mixcol->buffer) {
+ p->mixcol->start_time /= ABS (mix->segment.rate);
+ p->mixcol->end_time /= ABS (mix->segment.rate);
}
if (abs_rate != 1.0 && p->mixcol->buffer) {
p->mixcol->start_time *= abs_rate;
@@ -1343,7 +1315,7 @@ gst_videomixer2_src_event (GstPad * pad, GstEvent * event)
gst_segment_set_seek (&mix->segment, rate, fmt, flags, start_type, start,
stop_type, stop, NULL);
- mix->segment.last_stop = -1;
+ mix->segment.position = -1;
mix->ts_offset = 0;
mix->nframes = 0;
mix->newseg_pending = TRUE;
@@ -1414,8 +1386,8 @@ gst_videomixer2_src_setcaps (GstPad * pad, GstCaps * caps)
GST_VIDEO_MIXER2_LOCK (mix);
if (mix->fps_n != fps_n || mix->fps_d != fps_d) {
- if (mix->segment.last_stop != -1) {
- mix->ts_offset = mix->segment.last_stop - mix->segment.start;
+ if (mix->segment.position != -1) {
+ mix->ts_offset = mix->segment.position - mix->segment.start;
mix->nframes = 0;
}
gst_videomixer2_reset_qos (mix);
@@ -1611,9 +1583,9 @@ gst_videomixer2_sink_clip (GstCollectPads2 * pads,
GST_FORMAT_TIME, end_time);
/* Convert to the output segment rate */
- if (mix->segment.abs_rate != 1.0) {
- start_time *= mix->segment.abs_rate;
- end_time *= mix->segment.abs_rate;
+ if (ABS (mix->segment.rate) != 1.0) {
+ start_time *= ABS (mix->segment.rate);
+ end_time *= ABS (mix->segment.rate);
}
if (mixcol->buffer != NULL && end_time < mixcol->end_time) {
@@ -1656,7 +1628,7 @@ gst_videomixer2_sink_event (GstCollectPads2 * pads, GstCollectData2 * cdata,
pad->mixcol->end_time = -1;
gst_segment_init (&mix->segment, GST_FORMAT_TIME);
- mix->segment.last_stop = -1;
+ mix->segment.position = -1;
mix->ts_offset = 0;
mix->nframes = 0;
@@ -1925,22 +1897,6 @@ gst_videomixer2_child_proxy_init (gpointer g_iface, gpointer iface_data)
/* GObject boilerplate */
static void
-gst_videomixer2_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
-
- gst_element_class_set_details_simple (element_class, "Video mixer 2",
- "Filter/Editor/Video",
- "Mix multiple video streams", "Wim Taymans <wim@fluendo.com>, "
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
gst_videomixer2_class_init (GstVideoMixer2Class * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -1963,12 +1919,22 @@ gst_videomixer2_class_init (GstVideoMixer2Class * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_videomixer2_change_state);
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&src_factory));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_factory));
+
+ gst_element_class_set_details_simple (gstelement_class, "Video mixer 2",
+ "Filter/Editor/Video",
+ "Mix multiple video streams", "Wim Taymans <wim@fluendo.com>, "
+ "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
/* Register the pad class */
g_type_class_ref (GST_TYPE_VIDEO_MIXER2_PAD);
}
static void
-gst_videomixer2_init (GstVideoMixer2 * mix, GstVideoMixer2Class * g_class)
+gst_videomixer2_init (GstVideoMixer2 * mix)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (mix);
diff --git a/gst/videomixer/videomixer2.h b/gst/videomixer/videomixer2.h
index 1666cbb09..f4bab3111 100644
--- a/gst/videomixer/videomixer2.h
+++ b/gst/videomixer/videomixer2.h
@@ -86,12 +86,7 @@ struct _GstVideoMixer2
gint next_sinkpad;
/* Output caps */
- GstVideoFormat format;
- gint width, height;
- gint fps_n;
- gint fps_d;
- gint par_n;
- gint par_d;
+ GstVideoInfo info;
gboolean newseg_pending;
gboolean flush_stop_pending;
diff --git a/gst/videomixer/videomixer2pad.h b/gst/videomixer/videomixer2pad.h
index a2412dab4..d77519ceb 100644
--- a/gst/videomixer/videomixer2pad.h
+++ b/gst/videomixer/videomixer2pad.h
@@ -54,9 +54,7 @@ struct _GstVideoMixer2Pad
/* < private > */
/* caps */
- gint width, height;
- gint fps_n;
- gint fps_d;
+ GstVideoInfo info;
/* properties */
gint xpos, ypos;