mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
base: Improve negotiation with new getcaps() filter
This commit is contained in:
parent
3fa1594aaf
commit
bdf9022861
7 changed files with 173 additions and 109 deletions
|
@ -227,6 +227,9 @@ The 0.11 porting guide
|
|||
gst_collect_pads_read() removed, use _read_buffer() or _take_buffer() and
|
||||
then use the memory API to get to the memory.
|
||||
|
||||
|
||||
* GstBaseSrc, GstBaseTransform, GstBaseSink
|
||||
GstBaseSrc::get_caps(), GstBaseTransform::transform_caps() and
|
||||
GstBaseSink::get_caps() now take a filter GstCaps* parameter to
|
||||
filter the caps and allow better negotiation decisions.
|
||||
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ static gboolean gst_base_sink_send_event (GstElement * element,
|
|||
static gboolean gst_base_sink_query (GstElement * element, GstQuery ** query);
|
||||
static const GstQueryType *gst_base_sink_get_query_types (GstElement * element);
|
||||
|
||||
static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink);
|
||||
static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * caps);
|
||||
static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
|
||||
static void gst_base_sink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
|
||||
GstClockTime * start, GstClockTime * end);
|
||||
|
@ -390,7 +390,7 @@ static gboolean gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active);
|
|||
static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
|
||||
static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad);
|
||||
static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static void gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps);
|
||||
|
||||
/* check if an object was too late */
|
||||
|
@ -562,7 +562,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_sink_pad_getcaps (GstPad * pad)
|
||||
gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseSinkClass *bclass;
|
||||
GstBaseSink *bsink;
|
||||
|
@ -577,7 +577,7 @@ gst_base_sink_pad_getcaps (GstPad * pad)
|
|||
}
|
||||
if (caps == NULL) {
|
||||
if (bclass->get_caps)
|
||||
caps = bclass->get_caps (bsink);
|
||||
caps = bclass->get_caps (bsink, filter);
|
||||
|
||||
if (caps == NULL) {
|
||||
GstPadTemplate *pad_template;
|
||||
|
@ -587,6 +587,15 @@ gst_base_sink_pad_getcaps (GstPad * pad)
|
|||
"sink");
|
||||
if (pad_template != NULL) {
|
||||
caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
|
||||
|
||||
if (filter) {
|
||||
GstCaps *intersection;
|
||||
|
||||
intersection =
|
||||
gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (caps);
|
||||
caps = intersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1393,7 +1402,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
|
||||
|
||||
static GstCaps *
|
||||
gst_base_sink_get_caps (GstBaseSink * sink)
|
||||
gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * filter)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ struct _GstBaseSinkClass {
|
|||
GstElementClass parent_class;
|
||||
|
||||
/* get caps from subclass */
|
||||
GstCaps* (*get_caps) (GstBaseSink *sink);
|
||||
GstCaps* (*get_caps) (GstBaseSink *sink, GstCaps *filter);
|
||||
/* notify subclass of new caps */
|
||||
gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps);
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ gst_base_src_get_type (void)
|
|||
return base_src_type;
|
||||
}
|
||||
|
||||
static GstCaps *gst_base_src_getcaps (GstPad * pad);
|
||||
static GstCaps *gst_base_src_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static void gst_base_src_fixate (GstPad * pad, GstCaps * caps);
|
||||
|
||||
|
@ -786,7 +786,7 @@ gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_src_getcaps (GstPad * pad)
|
||||
gst_base_src_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseSrcClass *bclass;
|
||||
GstBaseSrc *bsrc;
|
||||
|
@ -795,7 +795,7 @@ gst_base_src_getcaps (GstPad * pad)
|
|||
bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
|
||||
bclass = GST_BASE_SRC_GET_CLASS (bsrc);
|
||||
if (bclass->get_caps)
|
||||
caps = bclass->get_caps (bsrc);
|
||||
caps = bclass->get_caps (bsrc, filter);
|
||||
|
||||
if (caps == NULL) {
|
||||
GstPadTemplate *pad_template;
|
||||
|
@ -804,6 +804,15 @@ gst_base_src_getcaps (GstPad * pad)
|
|||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
|
||||
if (pad_template != NULL) {
|
||||
caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
|
||||
|
||||
if (filter) {
|
||||
GstCaps *intersection;
|
||||
|
||||
intersection =
|
||||
gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (caps);
|
||||
caps = intersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
return caps;
|
||||
|
@ -2551,7 +2560,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
|
|||
gboolean result = FALSE;
|
||||
|
||||
/* first see what is possible on our source pad */
|
||||
thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
|
||||
thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc), NULL);
|
||||
GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
|
||||
/* nothing or anything is allowed, we're done */
|
||||
if (thiscaps == NULL || gst_caps_is_any (thiscaps))
|
||||
|
@ -2561,38 +2570,35 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
|
|||
goto no_caps;
|
||||
|
||||
/* get the peer caps */
|
||||
peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
|
||||
peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc), thiscaps);
|
||||
GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
|
||||
if (peercaps) {
|
||||
/* get intersection */
|
||||
caps =
|
||||
gst_caps_intersect_full (peercaps, thiscaps, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, caps);
|
||||
gst_caps_unref (peercaps);
|
||||
/* The result is already a subset of our caps */
|
||||
caps = peercaps;
|
||||
gst_caps_unref (thiscaps);
|
||||
} else {
|
||||
/* no peer, work with our own caps then */
|
||||
caps = gst_caps_copy (thiscaps);
|
||||
caps = thiscaps;
|
||||
}
|
||||
gst_caps_unref (thiscaps);
|
||||
if (caps) {
|
||||
if (caps && !gst_caps_is_empty (caps)) {
|
||||
caps = gst_caps_make_writable (caps);
|
||||
|
||||
/* take first (and best, since they are sorted) possibility */
|
||||
gst_caps_truncate (caps);
|
||||
|
||||
/* now fixate */
|
||||
if (!gst_caps_is_empty (caps)) {
|
||||
GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps);
|
||||
if (gst_caps_is_any (caps)) {
|
||||
/* hmm, still anything, so element can do anything and
|
||||
* nego is not needed */
|
||||
result = TRUE;
|
||||
} else {
|
||||
gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
|
||||
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
|
||||
if (gst_caps_is_fixed (caps)) {
|
||||
/* yay, fixed caps, use those then, it's possible that the subclass does
|
||||
* not accept this caps after all and we have to fail. */
|
||||
result = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
|
||||
}
|
||||
GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps);
|
||||
if (gst_caps_is_any (caps)) {
|
||||
/* hmm, still anything, so element can do anything and
|
||||
* nego is not needed */
|
||||
result = TRUE;
|
||||
} else {
|
||||
gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
|
||||
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
|
||||
if (gst_caps_is_fixed (caps)) {
|
||||
/* yay, fixed caps, use those then, it's possible that the subclass does
|
||||
* not accept this caps after all and we have to fail. */
|
||||
result = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
|
||||
}
|
||||
}
|
||||
gst_caps_unref (caps);
|
||||
|
|
|
@ -168,7 +168,7 @@ struct _GstBaseSrcClass {
|
|||
/* virtual methods for subclasses */
|
||||
|
||||
/* get caps from subclass */
|
||||
GstCaps* (*get_caps) (GstBaseSrc *src);
|
||||
GstCaps* (*get_caps) (GstBaseSrc *src, GstCaps *filter);
|
||||
/* notify the subclass of new caps */
|
||||
gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps);
|
||||
|
||||
|
|
|
@ -312,12 +312,12 @@ static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
|
|||
guint length, GstBuffer ** buffer);
|
||||
static GstFlowReturn gst_base_transform_chain (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
static GstCaps *gst_base_transform_getcaps (GstPad * pad);
|
||||
static GstCaps *gst_base_transform_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps);
|
||||
static gboolean gst_base_transform_setcaps (GstBaseTransform * trans,
|
||||
GstPad * pad, GstCaps * caps, gboolean reconfigure);
|
||||
GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_base_transform_query (GstPad * pad, GstQuery ** query);
|
||||
static const GstQueryType *gst_base_transform_query_type (GstPad * pad);
|
||||
|
||||
|
@ -450,7 +450,7 @@ gst_base_transform_init (GstBaseTransform * trans,
|
|||
*/
|
||||
static GstCaps *
|
||||
gst_base_transform_transform_caps (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps)
|
||||
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
||||
{
|
||||
GstCaps *ret;
|
||||
GstBaseTransformClass *klass;
|
||||
|
@ -472,9 +472,8 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
|
|||
if (gst_caps_is_any (caps)) {
|
||||
/* for any caps we still have to call the transform function */
|
||||
GST_DEBUG_OBJECT (trans, "from: ANY");
|
||||
temp = klass->transform_caps (trans, direction, caps);
|
||||
temp = klass->transform_caps (trans, direction, caps, filter);
|
||||
GST_DEBUG_OBJECT (trans, " to: %" GST_PTR_FORMAT, temp);
|
||||
|
||||
temp = gst_caps_make_writable (temp);
|
||||
gst_caps_append (ret, temp);
|
||||
} else {
|
||||
|
@ -486,8 +485,9 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
|
|||
|
||||
nth = gst_caps_copy_nth (caps, i);
|
||||
GST_LOG_OBJECT (trans, "from[%d]: %" GST_PTR_FORMAT, i, nth);
|
||||
temp = klass->transform_caps (trans, direction, nth);
|
||||
temp = klass->transform_caps (trans, direction, nth, filter);
|
||||
gst_caps_unref (nth);
|
||||
|
||||
GST_LOG_OBJECT (trans, " to[%d]: %" GST_PTR_FORMAT, i, temp);
|
||||
|
||||
temp = gst_caps_make_writable (temp);
|
||||
|
@ -505,10 +505,31 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
|
|||
GST_DEBUG_OBJECT (trans, "simplified: (%d)", gst_caps_get_size (ret));
|
||||
*/
|
||||
}
|
||||
|
||||
#ifndef G_DISABLE_ASSERT
|
||||
if (filter) {
|
||||
if (!gst_caps_is_subset (ret, filter)) {
|
||||
GST_ERROR_OBJECT (trans,
|
||||
"transform_caps returned caps %" GST_PTR_FORMAT
|
||||
" which are not a real subset of the filter caps %"
|
||||
GST_PTR_FORMAT, ret, filter);
|
||||
g_warning ("%s: transform_caps returned caps which are not a real "
|
||||
"subset of the filter caps", GST_ELEMENT_NAME (trans));
|
||||
|
||||
temp = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (ret);
|
||||
ret = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans, "identity from: %" GST_PTR_FORMAT, caps);
|
||||
/* no transform function, use the identity transform */
|
||||
ret = gst_caps_ref (caps);
|
||||
if (filter) {
|
||||
ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
} else {
|
||||
ret = gst_caps_ref (caps);
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (trans, "to: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (ret),
|
||||
|
@ -613,19 +634,52 @@ no_out_size:
|
|||
* If there is no peer, we simply return the caps of the padtemplate of pad.
|
||||
*/
|
||||
static GstCaps *
|
||||
gst_base_transform_getcaps (GstPad * pad)
|
||||
gst_base_transform_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseTransform *trans;
|
||||
GstPad *otherpad;
|
||||
GstCaps *peercaps, *caps;
|
||||
GstCaps *peercaps, *caps, *peerfilter = NULL;
|
||||
|
||||
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||
|
||||
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
|
||||
|
||||
/* we can do what the peer can */
|
||||
peercaps = gst_pad_peer_get_caps (otherpad);
|
||||
if (peercaps) {
|
||||
if (filter) {
|
||||
GstCaps *temp;
|
||||
const GstCaps *templ;
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "filter caps %" GST_PTR_FORMAT, filter);
|
||||
|
||||
/* filtered against our padtemplate on the other side */
|
||||
templ = gst_pad_get_pad_template_caps (pad);
|
||||
GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ);
|
||||
temp = gst_caps_intersect_full (filter, templ, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
|
||||
|
||||
/* then see what we can transform this to */
|
||||
peerfilter = gst_base_transform_transform_caps (trans,
|
||||
GST_PAD_DIRECTION (pad), temp, NULL);
|
||||
GST_DEBUG_OBJECT (pad, "transformed %" GST_PTR_FORMAT, peerfilter);
|
||||
gst_caps_unref (temp);
|
||||
|
||||
/* and filter against the template of this pad */
|
||||
templ = gst_pad_get_pad_template_caps (otherpad);
|
||||
GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ);
|
||||
/* We keep the caps sorted like the returned caps */
|
||||
temp =
|
||||
gst_caps_intersect_full (peerfilter, templ, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
|
||||
gst_caps_unref (peerfilter);
|
||||
peerfilter = temp;
|
||||
}
|
||||
|
||||
peercaps = gst_pad_peer_get_caps (otherpad, peerfilter);
|
||||
|
||||
if (peerfilter)
|
||||
gst_caps_unref (peerfilter);
|
||||
|
||||
if (peercaps && !gst_caps_is_any (peercaps)) {
|
||||
GstCaps *temp;
|
||||
const GstCaps *templ;
|
||||
|
||||
|
@ -639,7 +693,7 @@ gst_base_transform_getcaps (GstPad * pad)
|
|||
|
||||
/* then see what we can transform this to */
|
||||
caps = gst_base_transform_transform_caps (trans,
|
||||
GST_PAD_DIRECTION (otherpad), temp);
|
||||
GST_PAD_DIRECTION (otherpad), temp, filter);
|
||||
GST_DEBUG_OBJECT (pad, "transformed %" GST_PTR_FORMAT, caps);
|
||||
gst_caps_unref (temp);
|
||||
if (caps == NULL)
|
||||
|
@ -665,6 +719,14 @@ gst_base_transform_getcaps (GstPad * pad)
|
|||
} else {
|
||||
/* no peer or the peer can do anything, our padtemplate is enough then */
|
||||
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
|
||||
if (filter) {
|
||||
GstCaps *temp;
|
||||
|
||||
temp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (caps);
|
||||
caps = temp;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -740,7 +802,7 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
|
|||
*/
|
||||
static GstCaps *
|
||||
gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
|
||||
GstCaps * caps, gboolean reconfigure)
|
||||
GstCaps * caps)
|
||||
{
|
||||
GstBaseTransformClass *klass;
|
||||
GstPad *otherpad, *otherpeer;
|
||||
|
@ -760,7 +822,7 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
|
|||
* passthrough because it might be possible that this element cannot support
|
||||
* passthrough at all. */
|
||||
othercaps = gst_base_transform_transform_caps (trans,
|
||||
GST_PAD_DIRECTION (pad), caps);
|
||||
GST_PAD_DIRECTION (pad), caps, NULL);
|
||||
|
||||
/* The caps we can actually output is the intersection of the transformed
|
||||
* caps with the pad template for the pad */
|
||||
|
@ -789,71 +851,55 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
|
|||
/* FIXME. maybe the caps is not fixed because it has multiple structures of
|
||||
* fixed caps */
|
||||
is_fixed = gst_caps_is_fixed (othercaps);
|
||||
if (!is_fixed && !reconfigure) {
|
||||
if (!is_fixed) {
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"transform returned non fixed %" GST_PTR_FORMAT, othercaps);
|
||||
|
||||
/* see if the target caps are a superset of the source caps, in this
|
||||
* case we can try to perform passthrough */
|
||||
if (gst_caps_can_intersect (othercaps, caps)) {
|
||||
GST_DEBUG_OBJECT (trans, "try passthrough with %" GST_PTR_FORMAT, caps);
|
||||
if (otherpeer) {
|
||||
/* try passthrough. we know it's fixed, because caps is fixed */
|
||||
if (gst_pad_accept_caps (otherpeer, caps)) {
|
||||
GST_DEBUG_OBJECT (trans, "peer accepted %" GST_PTR_FORMAT, caps);
|
||||
/* peer accepted unmodified caps, we free the original non-fixed
|
||||
* caps and work with the passthrough caps */
|
||||
gst_caps_unref (othercaps);
|
||||
othercaps = gst_caps_ref (caps);
|
||||
is_fixed = TRUE;
|
||||
/* mark that we checked othercaps with the peer, this
|
||||
* makes sure we don't call accept_caps again with these same
|
||||
* caps */
|
||||
peer_checked = TRUE;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"peer did not accept %" GST_PTR_FORMAT, caps);
|
||||
}
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
|
||||
gst_caps_unref (othercaps);
|
||||
othercaps = gst_caps_ref (caps);
|
||||
is_fixed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Now let's see what the peer suggests based on our transformed caps */
|
||||
if (otherpeer) {
|
||||
GstCaps *peercaps, *intersection;
|
||||
const GstCaps *templ_caps;
|
||||
|
||||
/* second attempt at fixation is done by intersecting with
|
||||
* the peer caps */
|
||||
if (!is_fixed && otherpeer) {
|
||||
/* intersect against what the peer can do */
|
||||
GstCaps *peercaps;
|
||||
GstCaps *intersect;
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"Checking peer caps with filter %" GST_PTR_FORMAT, othercaps);
|
||||
|
||||
GST_DEBUG_OBJECT (trans, "othercaps now %" GST_PTR_FORMAT, othercaps);
|
||||
peercaps = gst_pad_get_caps (otherpeer, othercaps);
|
||||
GST_DEBUG_OBJECT (trans, "Resulted in %" GST_PTR_FORMAT, peercaps);
|
||||
|
||||
peercaps = gst_pad_get_caps (otherpeer);
|
||||
if (!reconfigure)
|
||||
intersect = gst_caps_intersect (peercaps, othercaps);
|
||||
else
|
||||
intersect =
|
||||
templ_caps = gst_pad_get_pad_template_caps (otherpad);
|
||||
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"Intersecting with template caps %" GST_PTR_FORMAT, templ_caps);
|
||||
|
||||
intersection =
|
||||
gst_caps_intersect_full (peercaps, templ_caps,
|
||||
GST_CAPS_INTERSECT_FIRST);
|
||||
GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
|
||||
gst_caps_unref (peercaps);
|
||||
peercaps = intersection;
|
||||
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"Intersecting with transformed caps %" GST_PTR_FORMAT, othercaps);
|
||||
intersection =
|
||||
gst_caps_intersect_full (peercaps, othercaps,
|
||||
GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (peercaps);
|
||||
gst_caps_unref (othercaps);
|
||||
othercaps = intersect;
|
||||
peer_checked = FALSE;
|
||||
|
||||
is_fixed = gst_caps_is_fixed (othercaps);
|
||||
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
"filtering against peer yields %" GST_PTR_FORMAT, othercaps);
|
||||
GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
|
||||
gst_caps_unref (peercaps);
|
||||
gst_caps_unref (othercaps);
|
||||
othercaps = intersection;
|
||||
is_fixed = gst_caps_is_fixed (othercaps);
|
||||
peer_checked = TRUE;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
|
||||
gst_caps_unref (othercaps);
|
||||
othercaps = gst_caps_ref (caps);
|
||||
is_fixed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (gst_caps_is_empty (othercaps))
|
||||
goto no_transform_possible;
|
||||
|
||||
/* third attempt at fixation, call the fixate vmethod and
|
||||
/* second attempt at fixation, call the fixate vmethod and
|
||||
* ultimately call the pad fixate function. */
|
||||
if (!is_fixed) {
|
||||
GST_DEBUG_OBJECT (trans,
|
||||
|
@ -978,9 +1024,9 @@ gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
|
|||
|
||||
/* get all the formats we can handle on this pad */
|
||||
if (direction == GST_PAD_SRC)
|
||||
allowed = gst_pad_get_caps (trans->srcpad);
|
||||
allowed = gst_pad_get_caps (trans->srcpad, NULL);
|
||||
else
|
||||
allowed = gst_pad_get_caps (trans->sinkpad);
|
||||
allowed = gst_pad_get_caps (trans->sinkpad, NULL);
|
||||
|
||||
if (!allowed) {
|
||||
GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed");
|
||||
|
@ -1058,7 +1104,7 @@ gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps)
|
|||
*/
|
||||
static gboolean
|
||||
gst_base_transform_setcaps (GstBaseTransform * trans, GstPad * pad,
|
||||
GstCaps * caps, gboolean reconfigure)
|
||||
GstCaps * caps)
|
||||
{
|
||||
GstPad *otherpad, *otherpeer;
|
||||
GstCaps *othercaps = NULL;
|
||||
|
@ -1076,7 +1122,7 @@ gst_base_transform_setcaps (GstBaseTransform * trans, GstPad * pad,
|
|||
GST_DEBUG_OBJECT (pad, "have new caps %p %" GST_PTR_FORMAT, caps, caps);
|
||||
|
||||
/* find best possible caps for the other pad */
|
||||
othercaps = gst_base_transform_find_transform (trans, pad, caps, reconfigure);
|
||||
othercaps = gst_base_transform_find_transform (trans, pad, caps);
|
||||
if (!othercaps || gst_caps_is_empty (othercaps))
|
||||
goto no_transform_possible;
|
||||
|
||||
|
@ -1528,7 +1574,7 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
|
|||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
gst_base_transform_setcaps (trans, trans->sinkpad, caps, FALSE);
|
||||
gst_base_transform_setcaps (trans, trans->sinkpad, caps);
|
||||
|
||||
forward = FALSE;
|
||||
break;
|
||||
|
@ -1643,7 +1689,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
/* if we need to reconfigure we pretend a buffer with new caps arrived. This
|
||||
* will reconfigure the transform with the new output format. We can only
|
||||
* do this if the buffer actually has caps. */
|
||||
if (!gst_base_transform_setcaps (trans, trans->sinkpad, incaps, TRUE)) {
|
||||
if (!gst_base_transform_setcaps (trans, trans->sinkpad, incaps)) {
|
||||
gst_caps_unref (incaps);
|
||||
goto not_negotiated;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ struct _GstBaseTransformClass {
|
|||
/* virtual methods for subclasses */
|
||||
GstCaps* (*transform_caps) (GstBaseTransform *trans,
|
||||
GstPadDirection direction,
|
||||
GstCaps *caps);
|
||||
GstCaps *caps, GstCaps *filter);
|
||||
|
||||
void (*fixate_caps) (GstBaseTransform *trans,
|
||||
GstPadDirection direction, GstCaps *caps,
|
||||
|
|
Loading…
Reference in a new issue