gboolean rb_gst_media_type_matches_profile (GstEncodingProfile *profile, const char *media_type) { const GstCaps *pcaps; const GList *cl; GstCaps *caps; gboolean matches = FALSE; caps = rb_gst_media_type_to_caps (media_type); if (caps == NULL) { return FALSE; } pcaps = gst_encoding_profile_get_format (profile); if (gst_caps_can_intersect (caps, pcaps)) { matches = TRUE; } if (matches == FALSE && GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { for (cl = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); cl != NULL; cl = cl->next) { GstEncodingProfile *cp = cl->data; pcaps = gst_encoding_profile_get_format (cp); if (gst_caps_can_intersect (caps, pcaps)) { matches = TRUE; break; } } } return matches; }
static gboolean check_bin (KmsTreeBin * tree_bin, const GstCaps * caps) { gboolean ret = FALSE; GstElement *output_tee = kms_tree_bin_get_output_tee (tree_bin); GstPad *tee_sink = gst_element_get_static_pad (output_tee, "sink"); GstCaps *current_caps = kms_tree_bin_get_input_caps (tree_bin); if (current_caps == NULL) { current_caps = gst_pad_get_allowed_caps (tee_sink); GST_TRACE_OBJECT (tree_bin, "Allowed caps are: %" GST_PTR_FORMAT, current_caps); } else { GST_TRACE_OBJECT (tree_bin, "Current caps are: %" GST_PTR_FORMAT, current_caps); } if (current_caps != NULL) { //TODO: Remove this when problem in negotiation with features will be //resolved GstCaps *caps_without_features = gst_caps_make_writable (current_caps); gst_caps_set_features (caps_without_features, 0, gst_caps_features_new_empty ()); if (gst_caps_can_intersect (caps, caps_without_features)) { ret = TRUE; } gst_caps_unref (caps_without_features); } g_object_unref (tee_sink); return ret; }
static gboolean check_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps) { GList *tmp; gboolean res = FALSE; g_mutex_lock (&dbin->factories_lock); gst_decode_bin_update_factories_list (dbin); for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) { GstElementFactory *factory = (GstElementFactory *) tmp->data; GstCaps *tcaps; const GList *tmps; GST_LOG ("Trying factory %s", gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory))); for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps; tmps = tmps->next) { GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data; if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS) continue; tcaps = gst_static_pad_template_get_caps (st); if (gst_caps_can_intersect (tcaps, caps)) { res = TRUE; gst_caps_unref (tcaps); goto beach; } gst_caps_unref (tcaps); } } beach: g_mutex_unlock (&dbin->factories_lock); GST_DEBUG_OBJECT (dbin, "Can intersect : %d", res); return res; }
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 CodecBlueprint * _find_matching_blueprint (FsCodec *codec, GList *blueprints) { GList *item = NULL; GstCaps *caps = NULL; caps = fs_codec_to_gst_caps (codec); if (!caps) { gchar *tmp = fs_codec_to_string (codec); GST_WARNING ("Could not transform codec into caps: %s", tmp); g_free (tmp); return NULL; } for (item = g_list_first (blueprints); item; item = g_list_next (item)) { CodecBlueprint *bp = item->data; if (gst_caps_can_intersect (caps, bp->rtp_caps)) break; } gst_caps_unref (caps); if (item) return item->data; else return NULL; }
static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstWaylandSink *sink = GST_WAYLAND_SINK (bsink); const GstStructure *structure; GstCaps *allowed_caps; gboolean ret = TRUE; GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); allowed_caps = gst_pad_get_caps (GST_BASE_SINK_PAD (bsink)); if (!gst_caps_can_intersect (allowed_caps, caps)) return FALSE; structure = gst_caps_get_structure (caps, 0); ret &= gst_structure_get_int (structure, "width", &sink->video_width); ret &= gst_structure_get_int (structure, "height", &sink->video_height); if (!ret) return FALSE; gst_caps_replace (&sink->caps, caps); return TRUE; }
/** * Returns true if any |aFactory| caps intersect with |aCaps| */ static bool SupportsCaps(GstElementFactory *aFactory, GstCaps *aCaps) { for (const GList *iter = gst_element_factory_get_static_pad_templates(aFactory); iter; iter = iter->next) { GstStaticPadTemplate *templ = static_cast<GstStaticPadTemplate *>(iter->data); if (templ->direction == GST_PAD_SRC) { continue; } GstCaps *caps = gst_static_caps_get(&templ->static_caps); if (!caps) { continue; } bool supported = gst_caps_can_intersect(caps, aCaps); gst_caps_unref(caps); if (supported) { return true; } } return false; }
static gboolean check_bin (KmsTreeBin * tree_bin, const GstCaps * caps) { gboolean ret = FALSE; GstElement *output_tee = kms_tree_bin_get_output_tee (tree_bin); GstPad *tee_sink = gst_element_get_static_pad (output_tee, "sink"); GstCaps *current_caps = kms_tree_bin_get_input_caps (tree_bin); if (current_caps == NULL) { current_caps = gst_pad_get_allowed_caps (tee_sink); GST_TRACE_OBJECT (tree_bin, "Allowed caps are: %" GST_PTR_FORMAT, current_caps); } else { gst_caps_ref (current_caps); GST_TRACE_OBJECT (tree_bin, "Current caps are: %" GST_PTR_FORMAT, current_caps); } if (current_caps != NULL) { if (gst_caps_can_intersect (caps, current_caps)) { ret = TRUE; } gst_caps_unref (current_caps); } g_object_unref (tee_sink); return ret; }
static gboolean check_container (GstDiscovererInfo *info, GstEncodingProfile *profile) { GstDiscovererStreamInfo *stream_info; GType stream_type; GstCaps *stream_caps; gboolean ret = FALSE; const GstCaps *profile_caps = gst_encoding_profile_get_format (profile); /* Top-level GstStreamInformation in the topology will be * the container */ stream_info = gst_discoverer_info_get_stream_info (info); stream_caps = gst_discoverer_stream_info_get_caps (stream_info); stream_type = G_TYPE_FROM_INSTANCE (stream_info); if (stream_type == GST_TYPE_DISCOVERER_CONTAINER_INFO && gst_caps_can_intersect (stream_caps, profile_caps)) ret = TRUE; else if (stream_type != GST_TYPE_DISCOVERER_CONTAINER_INFO && gst_caps_is_empty (profile_caps)) ret = TRUE; gst_discoverer_stream_info_unref (stream_info); gst_caps_unref (stream_caps); return ret; }
static gboolean _is_disabled (GList *codec_prefs, CodecBlueprint *bp) { GList *item = NULL; for (item = g_list_first (codec_prefs); item; item = g_list_next (item)) { FsCodec *codec = item->data; GstCaps *caps = NULL; gboolean ok = FALSE; /* Only check for DISABLE entries */ if (codec->id != FS_CODEC_ID_DISABLE) continue; caps = fs_codec_to_gst_caps (codec); if (!caps) continue; if (gst_caps_can_intersect (caps, bp->rtp_caps)) ok = TRUE; gst_caps_unref (caps); if (ok) return TRUE; } return FALSE; }
static gboolean grd_vnc_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps) { GrdVncSink *vnc_sink = GRD_VNC_SINK (base_sink); GstVideoInfo info; if (!gst_caps_can_intersect (vnc_sink->caps, caps)) { GST_ERROR_OBJECT (vnc_sink, "caps incompatible"); return FALSE; } if (!gst_video_info_from_caps (&info, caps)) { GST_ERROR_OBJECT (vnc_sink, "caps invalid"); } g_mutex_lock (&vnc_sink->lock); vnc_sink->video_width = info.width; vnc_sink->video_height = info.height; g_mutex_unlock (&vnc_sink->lock); return TRUE; }
/* Fetches a compatible pad on the target element which isn't already * linked */ static GstPad * get_compatible_unlinked_pad (GstElement * element, GESTrack * track) { GstPad *res = NULL; GstIterator *pads; gboolean done = FALSE; const GstCaps *srccaps; GValue paditem = { 0, }; if (G_UNLIKELY (track == NULL)) goto no_track; GST_DEBUG_OBJECT (element, " track %" GST_PTR_FORMAT, track); pads = gst_element_iterate_sink_pads (element); srccaps = ges_track_get_caps (track); GST_DEBUG ("srccaps %" GST_PTR_FORMAT, srccaps); while (!done) { switch (gst_iterator_next (pads, &paditem)) { case GST_ITERATOR_OK: { GstPad *testpad = g_value_get_object (&paditem); if (!gst_pad_is_linked (testpad)) { GstCaps *sinkcaps = gst_pad_query_caps (testpad, NULL); GST_DEBUG ("sinkccaps %" GST_PTR_FORMAT, sinkcaps); if (gst_caps_can_intersect (srccaps, sinkcaps)) { res = gst_object_ref (testpad); done = TRUE; } gst_caps_unref (sinkcaps); } g_value_reset (&paditem); } break; case GST_ITERATOR_DONE: case GST_ITERATOR_ERROR: done = TRUE; break; case GST_ITERATOR_RESYNC: gst_iterator_resync (pads); break; } } g_value_reset (&paditem); gst_iterator_free (pads); return res; no_track: { GST_ERROR ("No track to check against"); return NULL; } }
static GstPadProbeReturn kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { KmsAgnosticBin2 *self; GstCaps *current_caps; GstCaps *new_caps = NULL; GstEvent *event = gst_pad_probe_info_get_event (info); if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; } GST_TRACE_OBJECT (pad, "Event: %" GST_PTR_FORMAT, event); self = KMS_AGNOSTIC_BIN2 (user_data); gst_event_parse_caps (event, &new_caps); if (new_caps == NULL) { GST_ERROR_OBJECT (self, "Unexpected NULL caps"); return GST_PAD_PROBE_OK; } KMS_AGNOSTIC_BIN2_LOCK (self); current_caps = self->priv->input_caps; self->priv->input_caps = gst_caps_copy (new_caps); KMS_AGNOSTIC_BIN2_UNLOCK (self); GST_TRACE_OBJECT (user_data, "New caps event: %" GST_PTR_FORMAT, event); if (current_caps != NULL) { GstStructure *st; GST_TRACE_OBJECT (user_data, "Current caps: %" GST_PTR_FORMAT, current_caps); st = gst_caps_get_structure (current_caps, 0); // Remove famerate, width, height, streamheader that make unecessary // agnostic reconstruction happen gst_structure_remove_fields (st, "width", "height", "framerate", "streamheader", "codec_data", NULL); if (!gst_caps_can_intersect (new_caps, current_caps) && !is_raw_caps (current_caps) && !is_raw_caps (new_caps)) { GST_DEBUG_OBJECT (user_data, "Caps differ caps: %" GST_PTR_FORMAT, new_caps); kms_agnostic_bin2_configure_input (self, new_caps); } gst_caps_unref (current_caps); } else { GST_DEBUG_OBJECT (user_data, "No previous caps, starting"); kms_agnostic_bin2_configure_input (self, new_caps); } return GST_PAD_PROBE_OK; }
bool tcam_gst_can_intersect_simple(const GstCaps *caps, const gchar *capsstring) { GstCaps *tmpcaps = gst_caps_from_string(capsstring); gboolean ret = gst_caps_can_intersect(caps, tmpcaps); gst_caps_unref(tmpcaps); return ret; }
/* compares caps and returns 0 if they intersect */ static gint compare_media_caps (gconstpointer a, gconstpointer b) { CodecCap *element = (CodecCap *)a; GstCaps *c_caps = (GstCaps *)b; return !gst_caps_can_intersect (element->caps, c_caps); }
static gpointer _get_decoder_factories (gpointer arg) { GstElementClass *klass = arg; GList *factories; GstPadTemplate *templ = gst_element_class_get_pad_template (klass, "sink"); RsnDecFactoryFilterCtx ctx = { NULL, }; GstCaps *raw; gboolean raw_audio; GstRegistry *registry = gst_registry_get (); ctx.desired_caps = gst_pad_template_get_caps (templ); raw = gst_caps_from_string ("audio/x-raw,format=(string){ F32LE, F32BE, F64LE, F64BE }"); raw_audio = gst_caps_can_intersect (raw, ctx.desired_caps); if (raw_audio) { GstCaps *sub = gst_caps_subtract (ctx.desired_caps, raw); ctx.desired_caps = sub; } else { gst_caps_ref (ctx.desired_caps); } gst_caps_unref (raw); /* Set decoder caps to empty. Will be filled by the factory_filter */ ctx.decoder_caps = gst_caps_new_empty (); GST_DEBUG ("Finding factories for caps: %" GST_PTR_FORMAT, ctx.desired_caps); factories = gst_registry_feature_filter (registry, (GstPluginFeatureFilter) rsndec_factory_filter, FALSE, &ctx); /* If these are audio caps, we add audioconvert, which is not a decoder, but allows raw audio to go through relatively unmolested - this will come handy when we have to send placeholder silence to allow preroll for those DVDs which have titles with no audio track. */ if (raw_audio) { GstPluginFeature *feature; GST_DEBUG ("These are audio caps, adding audioconvert"); feature = gst_registry_find_feature (registry, "audioconvert", GST_TYPE_ELEMENT_FACTORY); if (feature) { factories = g_list_append (factories, feature); } else { GST_WARNING ("Could not find feature audioconvert"); } } factories = g_list_sort (factories, (GCompareFunc) sort_by_ranks); GST_DEBUG ("Available decoder caps %" GST_PTR_FORMAT, ctx.decoder_caps); gst_caps_unref (ctx.decoder_caps); gst_caps_unref (ctx.desired_caps); return factories; }
static gboolean _rtpbin_pad_have_data_callback (GstPad *pad, GstMiniObject *miniobj, gpointer user_data) { FsRtpSubStream *self = FS_RTP_SUB_STREAM (user_data); gboolean ret = TRUE; gboolean remove = FALSE; FsRtpSession *session; if (fs_rtp_session_has_disposed_enter (self->priv->session, NULL)) return FALSE; if (fs_rtp_sub_stream_has_stopped_enter (self)) { fs_rtp_session_has_disposed_exit (self->priv->session); return FALSE; } g_object_ref (self); session = g_object_ref (self->priv->session); FS_RTP_SESSION_LOCK (self->priv->session); if (!self->priv->codecbin || !self->codec || !self->priv->caps) { ret = FALSE; } else if (GST_IS_BUFFER (miniobj)) { if (!gst_caps_is_equal_fixed (GST_BUFFER_CAPS (miniobj), self->priv->caps)) { if (!gst_caps_can_intersect (GST_BUFFER_CAPS (miniobj), self->priv->caps)) ret = FALSE; } else { remove = TRUE; } } if (remove && self->priv->blocking_id) { gst_pad_remove_data_probe (pad, self->priv->blocking_id); self->priv->blocking_id = 0; } FS_RTP_SESSION_UNLOCK (self->priv->session); fs_rtp_sub_stream_has_stopped_exit (self); fs_rtp_session_has_disposed_exit (self->priv->session); g_object_unref (self); g_object_unref (session); return ret; }
static inline gboolean _gst_caps_can_intersect_safe (const GstCaps * a, const GstCaps * b) { if (a == b) return TRUE; if ((a == NULL) || (b == NULL)) return FALSE; return gst_caps_can_intersect (a, b); }
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 can_intersect_static_caps (GstCaps * caps, GstStaticCaps * caps1) { GstCaps *tmp; gboolean ret; tmp = gst_static_caps_get (caps1); ret = gst_caps_can_intersect (caps, tmp); gst_caps_unref (tmp); return ret; }
static gboolean gst_alsasink_acceptcaps (GstPad * pad, GstCaps * caps) { GstAlsaSink *alsa = GST_ALSA_SINK (gst_pad_get_parent_element (pad)); GstCaps *pad_caps; GstStructure *st; gboolean ret = FALSE; GstRingBufferSpec spec = { 0 }; pad_caps = gst_pad_get_caps_reffed (pad); if (pad_caps) { ret = gst_caps_can_intersect (pad_caps, caps); gst_caps_unref (pad_caps); if (!ret) goto done; } /* If we've not got fixed caps, creating a stream might fail, so let's just * return from here with default acceptcaps behaviour */ if (!gst_caps_is_fixed (caps)) goto done; /* parse helper expects this set, so avoid nasty warning * will be set properly later on anyway */ spec.latency_time = GST_SECOND; if (!gst_ring_buffer_parse_caps (&spec, caps)) goto done; /* Make sure input is framed (one frame per buffer) and can be payloaded */ switch (spec.type) { case GST_BUFTYPE_AC3: case GST_BUFTYPE_EAC3: case GST_BUFTYPE_DTS: case GST_BUFTYPE_MPEG: { gboolean framed = FALSE, parsed = FALSE; st = gst_caps_get_structure (caps, 0); gst_structure_get_boolean (st, "framed", &framed); gst_structure_get_boolean (st, "parsed", &parsed); if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0) goto done; } default: { } } ret = TRUE; done: gst_caps_replace (&spec.caps, NULL); gst_object_unref (alsa); return ret; }
static gboolean gst_stream_splitter_sink_setcaps (GstPad * pad, GstCaps * caps) { GstStreamSplitter *stream_splitter = (GstStreamSplitter *) GST_PAD_PARENT (pad); guint32 cookie; GList *tmp; gboolean res; GST_DEBUG_OBJECT (stream_splitter, "caps %" GST_PTR_FORMAT, caps); /* Try on all pads, choose the one that succeeds as the current stream */ STREAMS_LOCK (stream_splitter); resync: if (G_UNLIKELY (stream_splitter->srcpads == NULL)) { res = FALSE; goto beach; } res = FALSE; tmp = stream_splitter->srcpads; cookie = stream_splitter->cookie; while (tmp) { GstPad *srcpad = (GstPad *) tmp->data; GstCaps *peercaps; STREAMS_UNLOCK (stream_splitter); peercaps = gst_pad_peer_query_caps (srcpad, NULL); if (peercaps) { res = gst_caps_can_intersect (caps, peercaps); gst_caps_unref (peercaps); } STREAMS_LOCK (stream_splitter); if (G_UNLIKELY (cookie != stream_splitter->cookie)) goto resync; if (res) { /* FIXME : we need to switch properly */ GST_DEBUG_OBJECT (srcpad, "Setting caps on this pad was successful"); stream_splitter->current = srcpad; goto beach; } tmp = tmp->next; } beach: STREAMS_UNLOCK (stream_splitter); return res; }
static gboolean gst_play_sink_convert_bin_acceptcaps (GstPad * pad, GstCaps * caps) { GstCaps *allowed_caps; gboolean ret; allowed_caps = gst_pad_query_caps (pad, NULL); /* FIXME 0.11: Should be a subset check now */ ret = gst_caps_can_intersect (caps, allowed_caps); gst_caps_unref (allowed_caps); return ret; }
bool tcam_gst_contains_bayer_16_bit (const GstCaps* caps) { if (caps == nullptr) { return false; } GstCaps* tmp = gst_caps_from_string("video/x-bayer, format={rggb16, bggr16, gbrg16, grbg16}"); gboolean ret = gst_caps_can_intersect(caps, tmp); gst_caps_unref(tmp); return ret; }
static void sink_check_caps (GstPad * pad, GstCaps * caps) { GstCaps *tcaps = gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, "format", G_TYPE_STRING, "S16BE", "layout", G_TYPE_STRING, "interleaved", NULL); fail_unless (gst_caps_can_intersect (caps, tcaps)); gst_caps_unref (tcaps); }
/** * @brief This function handles sink pad query. */ static gboolean gst_tensor_aggregator_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstTensorAggregator *self; self = GST_TENSOR_AGGREGATOR (parent); GST_DEBUG_OBJECT (self, "Received %s query: %" GST_PTR_FORMAT, GST_QUERY_TYPE_NAME (query), query); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS: { GstCaps *caps; GstCaps *filter; gst_query_parse_caps (query, &filter); caps = gst_tensor_aggregator_query_caps (self, pad, filter); gst_query_set_caps_result (query, caps); gst_caps_unref (caps); return TRUE; } case GST_QUERY_ACCEPT_CAPS: { GstCaps *caps; GstCaps *template_caps; gboolean res = FALSE; gst_query_parse_accept_caps (query, &caps); silent_debug_caps (caps, "accept-caps"); if (gst_caps_is_fixed (caps)) { template_caps = gst_pad_get_pad_template_caps (pad); res = gst_caps_can_intersect (template_caps, caps); gst_caps_unref (template_caps); } gst_query_set_accept_caps_result (query, res); return TRUE; } default: break; } return gst_pad_query_default (pad, parent, query); }
static void bus_sync_message (GstBus * bus, GstMessage * message, GstDeviceMonitor * monitor) { GstMessageType type = GST_MESSAGE_TYPE (message); if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) { gboolean matches; GstDevice *device; GstDeviceProvider *provider; if (type == GST_MESSAGE_DEVICE_ADDED) gst_message_parse_device_added (message, &device); else gst_message_parse_device_removed (message, &device); GST_OBJECT_LOCK (monitor); provider = GST_DEVICE_PROVIDER (gst_object_get_parent (GST_OBJECT (device))); if (is_provider_hidden (monitor, monitor->priv->hidden, provider)) { matches = FALSE; } else if (monitor->priv->filters->len) { guint i; for (i = 0; i < monitor->priv->filters->len; i++) { struct DeviceFilter *filter = g_ptr_array_index (monitor->priv->filters, i); GstCaps *caps; caps = gst_device_get_caps (device); matches = gst_caps_can_intersect (filter->caps, caps) && gst_device_has_classesv (device, filter->classesv); gst_caps_unref (caps); if (matches) break; } } else { matches = TRUE; } GST_OBJECT_UNLOCK (monitor); gst_object_unref (provider); gst_object_unref (device); if (matches) gst_bus_post (monitor->priv->bus, gst_message_ref (message)); } }
/** * gst_element_factory_list_filter: * @list: (transfer none) (element-type Gst.ElementFactory): a #GList of * #GstElementFactory to filter * @caps: a #GstCaps * @direction: a #GstPadDirection to filter on * @subsetonly: whether to filter on caps subsets or not. * * Filter out all the elementfactories in @list that can handle @caps in * the given direction. * * If @subsetonly is %TRUE, then only the elements whose pads templates * are a complete superset of @caps will be returned. Else any element * whose pad templates caps can intersect with @caps will be returned. * * Returns: (transfer full) (element-type Gst.ElementFactory): a #GList of * #GstElementFactory elements that match the given requisits. * Use #gst_plugin_feature_list_free after usage. * * Since: 0.10.31 */ GList * gst_element_factory_list_filter (GList * list, const GstCaps * caps, GstPadDirection direction, gboolean subsetonly) { GQueue results = G_QUEUE_INIT; GST_DEBUG ("finding factories"); /* loop over all the factories */ for (; list; list = list->next) { GstElementFactory *factory; const GList *templates; GList *walk; factory = (GstElementFactory *) list->data; GST_DEBUG ("Trying %s", gst_plugin_feature_get_name ((GstPluginFeature *) factory)); /* get the templates from the element factory */ templates = gst_element_factory_get_static_pad_templates (factory); for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { GstStaticPadTemplate *templ = walk->data; /* we only care about the sink templates */ if (templ->direction == direction) { GstCaps *tmpl_caps; /* try to intersect the caps with the caps of the template */ tmpl_caps = gst_static_caps_get (&templ->static_caps); /* FIXME, intersect is not the right method, we ideally want to check * for a subset here */ /* check if the intersection is empty */ if ((subsetonly && gst_caps_is_subset (caps, tmpl_caps)) || (!subsetonly && gst_caps_can_intersect (caps, tmpl_caps))) { /* non empty intersection, we can use this element */ g_queue_push_tail (&results, gst_object_ref (factory)); gst_caps_unref (tmpl_caps); break; } gst_caps_unref (tmpl_caps); } } } return results.head; }
/* Probing functions */ gboolean gst_v4l2_is_h264_enc (GstCaps * sink_caps, GstCaps * src_caps) { gboolean ret = FALSE; GstCaps *codec_caps; codec_caps = gst_static_caps_get (&src_template_caps); if (gst_caps_is_subset (sink_caps, gst_v4l2_object_get_raw_caps ()) && gst_caps_can_intersect (src_caps, codec_caps)) ret = TRUE; gst_caps_unref (codec_caps); return ret; }
static gboolean can_sink_caps (GstElement * e, GstCaps * caps) { gboolean res = FALSE; GstPad *sink = gst_element_get_static_pad (e, "sink"); if (sink) { GstCaps *sink_caps = gst_pad_get_caps (sink); if (sink_caps) { res = gst_caps_can_intersect (sink_caps, caps); gst_caps_unref (sink_caps); } gst_object_unref (sink); } return res; }