gst/videorate/gstvideorate.c: Better negotiation.

Original commit message from CVS:
* gst/videorate/gstvideorate.c: (gst_videorate_transformcaps),
(gst_videorate_getcaps), (gst_videorate_setcaps),
(gst_videorate_event), (gst_videorate_chain):
Better negotiation.
This commit is contained in:
Wim Taymans 2005-05-09 14:33:05 +00:00
parent fe62a9caa2
commit 13803bc40f
2 changed files with 62 additions and 50 deletions

View file

@ -1,3 +1,10 @@
2005-05-09 Wim Taymans <wim@fluendo.com>
* gst/videorate/gstvideorate.c: (gst_videorate_transformcaps),
(gst_videorate_getcaps), (gst_videorate_setcaps),
(gst_videorate_event), (gst_videorate_chain):
Better negotiation.
2005-05-09 Wim Taymans <wim@fluendo.com> 2005-05-09 Wim Taymans <wim@fluendo.com>
* gst/videorate/gstvideorate.c: (gst_videorate_class_init), * gst/videorate/gstvideorate.c: (gst_videorate_class_init),

View file

@ -196,6 +196,32 @@ gst_videorate_class_init (GstVideorateClass * klass)
element_class->change_state = gst_videorate_change_state; element_class->change_state = gst_videorate_change_state;
} }
/* return the caps that can be used on out_pad given in_caps on in_pad */
static gboolean
gst_videorate_transformcaps (GstPad * in_pad, GstCaps * in_caps,
GstPad * out_pad, GstCaps ** out_caps)
{
GstCaps *intersect;
const GstCaps *in_templ;
gint i;
in_templ = gst_pad_get_pad_template_caps (in_pad);
intersect = gst_caps_intersect (in_caps, in_templ);
/* all possible framerates are allowed */
for (i = 0; i < gst_caps_get_size (intersect); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (intersect, i);
gst_structure_set (structure,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
}
*out_caps = intersect;
return TRUE;
}
static GstCaps * static GstCaps *
gst_videorate_getcaps (GstPad * pad) gst_videorate_getcaps (GstPad * pad)
{ {
@ -211,25 +237,11 @@ gst_videorate_getcaps (GstPad * pad)
/* we can do what the peer can */ /* we can do what the peer can */
caps = gst_pad_peer_get_caps (otherpad); caps = gst_pad_peer_get_caps (otherpad);
if (caps) { if (caps) {
int i; GstCaps *transform;
GstCaps *intersect;
/* filter against our caps */ gst_videorate_transformcaps (otherpad, caps, pad, &transform);
intersect = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad));
gst_caps_unref (caps); gst_caps_unref (caps);
caps = intersect; caps = transform;
caps = gst_caps_make_writable (caps);
/* all possible framerates are allowed */
for (i = 0; i < gst_caps_get_size (caps); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (caps, i);
gst_structure_set (structure,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
}
} else { } else {
/* no peer, our padtemplate is enough then */ /* no peer, our padtemplate is enough then */
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
@ -271,34 +283,29 @@ gst_videorate_setcaps (GstPad * pad, GstCaps * caps)
} else { } else {
GstCaps *peercaps; GstCaps *peercaps;
GstCaps *intersect; GstCaps *intersect;
gint i; GstCaps *transform = NULL;
/* the peer does not accept this caps, see what it can do */ ret = FALSE;
/* see how we can transform the input caps */
if (!gst_videorate_transformcaps (pad, caps, otherpad, &transform))
goto done;
/* see what the peer can do */
peercaps = gst_pad_get_caps (opeer); peercaps = gst_pad_get_caps (opeer);
caps = gst_caps_make_writable (caps); /* filter against our possibilities */
intersect = gst_caps_intersect (peercaps, transform);
gst_caps_unref (peercaps);
gst_caps_unref (transform);
/* take first possibility */
caps = gst_caps_copy_nth (intersect, 0);
gst_caps_unref (intersect);
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
/* remove the framerate */ /* and fixate */
gst_structure_remove_field (structure, "framerate"); if (gst_caps_structure_fixate_field_nearest_int (structure, "framerate",
/* get all possibilities without framerate */
intersect = gst_caps_intersect (peercaps, caps);
gst_caps_unref (peercaps);
if (gst_caps_is_empty (intersect)) {
/* nothing possible, we're done */
gst_caps_unref (intersect);
ret = FALSE;
goto done;
}
/* loop through the caps, fixate the framerate */
for (i = 0; i < gst_caps_get_size (intersect); i++) {
GstStructure *istruct;
istruct = gst_caps_get_structure (intersect, i);
if (gst_caps_structure_fixate_field_nearest_int (istruct, "framerate",
fps)) { fps)) {
gst_structure_get_double (structure, "framerate", &fps); gst_structure_get_double (structure, "framerate", &fps);
if (otherpad == videorate->srcpad) { if (otherpad == videorate->srcpad) {
@ -306,12 +313,10 @@ gst_videorate_setcaps (GstPad * pad, GstCaps * caps)
} else { } else {
videorate->from_fps = fps; videorate->from_fps = fps;
} }
gst_pad_set_caps (otherpad, intersect); gst_pad_set_caps (otherpad, caps);
break; ret = TRUE;
} }
} }
gst_caps_unref (intersect);
}
gst_object_unref (GST_OBJECT (opeer)); gst_object_unref (GST_OBJECT (opeer));
} }
done: done: