From 13803bc40fad386850a6cdab47d9d4638ba9f0db Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 9 May 2005 14:33:05 +0000 Subject: [PATCH] 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. --- ChangeLog | 7 +++ gst/videorate/gstvideorate.c | 105 ++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 000ef3f8f5..17c5370ba5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-05-09 Wim Taymans + + * 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 * gst/videorate/gstvideorate.c: (gst_videorate_class_init), diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index 552e95211a..9dcebe71c0 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -196,6 +196,32 @@ gst_videorate_class_init (GstVideorateClass * klass) 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 * gst_videorate_getcaps (GstPad * pad) { @@ -211,25 +237,11 @@ gst_videorate_getcaps (GstPad * pad) /* we can do what the peer can */ caps = gst_pad_peer_get_caps (otherpad); if (caps) { - int i; - GstCaps *intersect; + GstCaps *transform; - /* filter against our caps */ - intersect = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad)); + gst_videorate_transformcaps (otherpad, caps, pad, &transform); gst_caps_unref (caps); - caps = intersect; - - 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); - } + caps = transform; } else { /* no peer, our padtemplate is enough then */ caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); @@ -271,46 +283,39 @@ gst_videorate_setcaps (GstPad * pad, GstCaps * caps) } else { GstCaps *peercaps; 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); - 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); - /* remove the framerate */ - gst_structure_remove_field (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)) { - gst_structure_get_double (structure, "framerate", &fps); - if (otherpad == videorate->srcpad) { - videorate->to_fps = fps; - } else { - videorate->from_fps = fps; - } - gst_pad_set_caps (otherpad, intersect); - break; + /* and fixate */ + if (gst_caps_structure_fixate_field_nearest_int (structure, "framerate", + fps)) { + gst_structure_get_double (structure, "framerate", &fps); + if (otherpad == videorate->srcpad) { + videorate->to_fps = fps; + } else { + videorate->from_fps = fps; } + gst_pad_set_caps (otherpad, caps); + ret = TRUE; } - gst_caps_unref (intersect); } gst_object_unref (GST_OBJECT (opeer)); }