static gboolean gst_capsfilter_accept_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps) { GstCapsFilter *capsfilter = GST_CAPSFILTER (base); GstCaps *filter_caps; gboolean ret; GST_OBJECT_LOCK (capsfilter); filter_caps = gst_caps_ref (capsfilter->filter_caps); GST_OBJECT_UNLOCK (capsfilter); ret = gst_caps_can_intersect (caps, filter_caps); GST_DEBUG_OBJECT (capsfilter, "can intersect: %d", ret); if (ret) { /* if we can intersect, see if the other end also accepts */ if (direction == GST_PAD_SRC) ret = gst_pad_peer_query_accept_caps (GST_BASE_TRANSFORM_SINK_PAD (base), caps); else ret = gst_pad_peer_query_accept_caps (GST_BASE_TRANSFORM_SRC_PAD (base), caps); GST_DEBUG_OBJECT (capsfilter, "peer accept: %d", ret); } gst_caps_unref (filter_caps); return ret; }
static gboolean gst_frei0r_mixer_set_caps (GstFrei0rMixer * self, GstPad * pad, GstCaps * caps) { gboolean ret = TRUE; if (!self->caps) { gst_caps_replace (&self->caps, caps); ret = gst_pad_set_caps (self->src, caps); if (ret) { GstVideoInfo info; gst_video_info_init (&info); if (!gst_video_info_from_caps (&self->info, caps)) { ret = FALSE; } } } else if (!gst_caps_is_equal (caps, self->caps)) { if (gst_pad_peer_query_accept_caps (pad, self->caps)) gst_pad_push_event (pad, gst_event_new_reconfigure ()); ret = FALSE; } return ret; }
static gboolean kms_recorder_endpoint_query_accept_caps (KmsElement * element, GstPad * pad, GstQuery * query) { KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (element); GstCaps *caps, *accept; GstElement *appsrc; gboolean ret = TRUE; switch (kms_element_get_pad_type (element, pad)) { case KMS_ELEMENT_PAD_TYPE_VIDEO: g_object_get (self->priv->mux, KMS_MUXING_PIPELINE_VIDEO_APPSRC, &appsrc, NULL); caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_VIDEO); break; case KMS_ELEMENT_PAD_TYPE_AUDIO: g_object_get (self->priv->mux, KMS_MUXING_PIPELINE_AUDIO_APPSRC, &appsrc, NULL); caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_AUDIO); break; default: GST_ERROR_OBJECT (pad, "unknown pad"); return FALSE; } if (caps == NULL) { GST_ERROR_OBJECT (self, "Can not accept caps without profile"); gst_query_set_accept_caps_result (query, FALSE); g_object_unref (appsrc); return TRUE; } gst_query_parse_accept_caps (query, &accept); ret = gst_caps_can_intersect (accept, caps); if (ret) { GstPad *srcpad; srcpad = gst_element_get_static_pad (appsrc, "src"); ret = gst_pad_peer_query_accept_caps (srcpad, accept); gst_object_unref (srcpad); } else { GST_ERROR_OBJECT (self, "Incompatbile caps %" GST_PTR_FORMAT, caps); } gst_caps_unref (caps); g_object_unref (appsrc); gst_query_set_accept_caps_result (query, ret); return TRUE; }
static gboolean gst_stream_splitter_sink_acceptcaps (GstPad * pad, GstCaps * caps) { GstStreamSplitter *stream_splitter = (GstStreamSplitter *) GST_PAD_PARENT (pad); guint32 cookie; GList *tmp; gboolean res = FALSE; /* check if one of the downstream elements accepts the caps */ STREAMS_LOCK (stream_splitter); resync: res = FALSE; if (G_UNLIKELY (stream_splitter->srcpads == NULL)) goto beach; cookie = stream_splitter->cookie; tmp = stream_splitter->srcpads; while (tmp) { GstPad *srcpad = (GstPad *) tmp->data; /* Ensure srcpad doesn't get destroyed while we query peer */ gst_object_ref (srcpad); STREAMS_UNLOCK (stream_splitter); res = gst_pad_peer_query_accept_caps (srcpad, caps); STREAMS_LOCK (stream_splitter); gst_object_unref (srcpad); if (G_UNLIKELY (cookie != stream_splitter->cookie)) goto resync; if (res) break; tmp = tmp->next; } beach: STREAMS_UNLOCK (stream_splitter); return res; }
static gboolean gst_identity_accept_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps) { gboolean ret; GstPad *pad; /* Proxy accept-caps */ if (direction == GST_PAD_SRC) pad = GST_BASE_TRANSFORM_SINK_PAD (base); else pad = GST_BASE_TRANSFORM_SRC_PAD (base); ret = gst_pad_peer_query_accept_caps (pad, caps); return ret; }
static gboolean kms_recorder_endpoint_query_accept_caps (KmsElement * element, GstPad * pad, GstQuery * query) { KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (element); GstCaps *caps, *accept; gboolean ret = TRUE; switch (kms_element_get_pad_type (element, pad)) { case KMS_ELEMENT_PAD_TYPE_VIDEO: caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_VIDEO); break; case KMS_ELEMENT_PAD_TYPE_AUDIO: caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_AUDIO); break; default: GST_ERROR_OBJECT (pad, "unknown pad"); return FALSE; } if (caps == NULL) { GST_ERROR_OBJECT (self, "Can not accept caps without profile"); gst_query_set_accept_caps_result (query, FALSE); return TRUE; } gst_query_parse_accept_caps (query, &accept); ret = gst_caps_can_intersect (accept, caps); if (ret) { GstElement *appsrc; GstPad *srcpad; gchar *id; id = gst_pad_get_name (pad); KMS_ELEMENT_LOCK (KMS_ELEMENT (self)); appsrc = g_hash_table_lookup (self->priv->srcs, id); g_free (id); if (appsrc == NULL) { KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); GST_DEBUG_OBJECT (self, "No appsrc attached to pad %" GST_PTR_FORMAT, pad); goto end; } srcpad = gst_element_get_static_pad (appsrc, "src"); KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); ret = gst_pad_peer_query_accept_caps (srcpad, accept); gst_object_unref (srcpad); } else { GST_ERROR_OBJECT (self, "Incompatbile caps %" GST_PTR_FORMAT, caps); } end: gst_caps_unref (caps); gst_query_set_accept_caps_result (query, ret); return TRUE; }
static gboolean gst_image_freeze_sink_setcaps (GstImageFreeze * self, GstCaps * caps) { gboolean ret = FALSE; GstStructure *s; gint fps_n, fps_d; GstCaps *othercaps, *intersection; guint i, n; GstPad *pad; pad = self->sinkpad; caps = gst_caps_make_writable (gst_caps_ref (caps)); GST_DEBUG_OBJECT (pad, "Setting caps: %" GST_PTR_FORMAT, caps); s = gst_caps_get_structure (caps, 0); /* 1. Remove framerate */ gst_structure_remove_field (s, "framerate"); gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); /* 2. Intersect with template caps */ othercaps = (GstCaps *) gst_pad_get_pad_template_caps (pad); intersection = gst_caps_intersect (caps, othercaps); GST_DEBUG_OBJECT (pad, "Intersecting: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (pad, "with: %" GST_PTR_FORMAT, othercaps); GST_DEBUG_OBJECT (pad, "gave: %" GST_PTR_FORMAT, intersection); gst_caps_unref (caps); gst_caps_unref (othercaps); caps = intersection; intersection = othercaps = NULL; /* 3. Intersect with downstream peer caps */ othercaps = gst_pad_peer_query_caps (self->srcpad, caps); GST_DEBUG_OBJECT (pad, "Peer query resulted: %" GST_PTR_FORMAT, othercaps); gst_caps_unref (caps); caps = othercaps; othercaps = NULL; /* 4. For every candidate check if it's accepted downstream * and fixate framerate to nearest 25/1 */ n = gst_caps_get_size (caps); for (i = 0; i < n; i++) { GstCaps *candidate = gst_caps_new_empty (); GstStructure *s = gst_structure_copy (gst_caps_get_structure (caps, i)); gst_caps_append_structure (candidate, s); if (gst_structure_has_field_typed (s, "framerate", GST_TYPE_FRACTION) || gst_structure_fixate_field_nearest_fraction (s, "framerate", 25, 1)) { if (gst_pad_peer_query_accept_caps (self->srcpad, candidate)) { gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d); if (fps_d != 0) { g_mutex_lock (&self->lock); self->fps_n = fps_n; self->fps_d = fps_d; g_mutex_unlock (&self->lock); GST_DEBUG_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, candidate); gst_pad_set_caps (self->srcpad, candidate); gst_caps_unref (candidate); ret = TRUE; goto done; } else { GST_WARNING_OBJECT (pad, "Invalid caps with framerate %d/%d", fps_n, fps_d); } } } gst_caps_unref (candidate); } done: if (!ret) GST_ERROR_OBJECT (pad, "No usable caps found"); gst_caps_unref (caps); return ret; }