the current capsnegotiation sucks and plainly doesn't work for queues. one of the reasons is that the core is trying to do too much, like being a mediator in the negotiation process. There is also way too much interaction between plugins. Plugins have to keep a lot of state too. The proposed method works by sending chains of caps instead, requiring a worst case of 2 interactions between plugins. The drawback is that a negotiating plugin has to do a bit more work, but in pactice this is not a real argument against the proposed method, as the actions it has to perform cannot be avoided. We will provide sufficient APIs to facilitate this. We are not going to send random chains of caps between plugins but we are going to filter them by using a new gst_caps_intersect() function that can find the common media types and properties between the plugins. The main idea is that the simple case should remain simple. We also introduce app specific filters that can be set while doing a pad connection. We proceed with a few use cases because they tend to explain the ideas better. use case 1 ---------- v4lsrc -> xvideosink no pad restrictions set on pad_connect v4lsrc can do many formats, so can xvideosink - v4lsrc request caps: width and height properties were set on v4lsrc so it provides them as hints. GstCaps *peercaps = gst_pad_request_caps (v4lsrc->srcpad, GST_CAPS_NEW ( "v4lsrc_srccaps", "video/raw", "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288))); - core fetches xvideosink caps. if xvideosink has a request_caps function, then the intersection of the hint, v4lsrcpad template caps and xvideosink sinkpad template are sent as input. If xvideosink has no request_caps function, the padtemplate caps of xvideosink are taken. - after intersect on both caps, peercaps equals: peercaps == gst_caps_chain ( GST_CAPS_NEW ( "xvideosink_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ), GST_CAPS_NEW ( "xvideosink_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ), GST_CAPS_NEW ( "xvideosink_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ), GST_CAPS_NEW ( "xvideosink_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("UYVY")), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ), GST_CAPS_NEW ( "xvideosink_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), "bpp", GST_PROPS_INT (16), "depth", GST_PROPS_INT (16), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "red_mask", GST_PROPS_INT (0xf800), "green_mask", GST_PROPS_INT (0x07e0), "blue_mask", GST_PROPS_INT (0x001f), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ) ) - v4lsrc does: while (peercaps) { /* check if the caps can be used */ if (caps_are_useful (peercaps)) { break; } ... peercaps = gst_caps_new (peercaps); } gst_pad_set_caps (v4lsrc->srcpad, peercaps); - core check compatibility with v4lsrc and xvideosink caps. if all goes well caps are set on the pads. - negotiation was more effective if v4lsrc provided srcpad caps since maybe YUY2 etc could be removed in the intersect (when v4lsrc doesn't support that format). use case 2 ---------- mpeg2dec -> colorspace -> xvideosink - mpeg2dec does: gst_pad_set_caps (mpeg2dec->srcpad, GST_CAPS_NEW ( "mpeg2dec_srccaps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT (720), "height", GST_PROPS_INT (480) ) ); - core checks compatibility with mpeg2dec srcpad caps and colorspace caps. - newcaps function of colorspace is called. - colorspace requests peer pad caps with the hint. - xvideosink doesn't have a request_caps function, the hint is ignored and the padtemplate caps are returned. - colorspace runs intersect on the two caps. - if the intersection is NULL, colorspace has to set up a conversion function. - runs through the list of caps, picking the first one for which a converter exists between the received caps and the target caps. set up the converter and set the target caps on the srcpad. - if the intersection is not NULL, set received caps on colorspace srcpad. use case 3 ---------- mpeg2dec -> queue -> colorspace -> queue -> xvideosink Same as use case 2, really. the queue just forwards the caps and the request caps. can we use a default implementation for this proxying? probably. for an element with no newcaps function or request_caps function, we can simply set the caps on all srcpads when a set_caps is performed, or we can request and intersect all srcpad caps when a peer element does request_caps. This will actually work for tee too, to some degree. use case 4 ---------- gst_pad_connect_caps (...), gst_element_connect_caps (v4lsrc, "src", xvideosink, "sink", GST_CAPS_NEW ( "app_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT (352), "height", GST_PROPS_INT (288) ) ); - as long as the connection is not broken, the caps are set as a filter to the to pads. - when v4lsrc requests pads, the intersection with the filter is also made. - v4lsrc has no other choice but to use I420. use case 5 ---------- mad -> osssink in this case, mad can both send "int" audio samples and "float" samples. - mad request_caps from osssink, sending the fixed properties as hints (rate, channels, ...) - osssink has a request_caps function, the core first makes the intersection between the hint and mad srcpad template. the core then does the intersection between osssink sinkpad template and sends this list to osssinks request_caps function. osssink can try this list (or whatever remains of it) and whatever works is sent back as the return value of the request_caps function. - mad receives the caps list, takes the top caps and does a pad_set_caps - osssink recieves the final caps on its new_caps function and configures the oss driver. use case 6 ---------- gsm -> audioscaler -> osssink Somebody sets some crazy low rate on the gsm srcpad (1000Hz). - audioscalers newcaps function is called. - audioscaler does a request_caps on its srcpad with the provided caps as a hint. - osssink tries the caps in the request_caps function (by opening the device, seeing that it doesn't support this rate at all...) - osssink tries to comply as closely with the rate and sends the intersection between its padtemplate caps and the findings (rate 8000Hz is possible). - audioscaler does the intersection between the caps list and the hint. - intersection == NULL, a converter is needed between the hint and the first caps of the request_caps list. - intersection != NULL, set those caps (== the hint).