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 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 kms_recorder_endpoint_query_caps (KmsElement * element, GstPad * pad, GstQuery * query) { KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (element); GstCaps *allowed = NULL, *caps = NULL; GstCaps *filter, *result, *tcaps; GstPad *target; target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); if (target == NULL) { GST_ERROR_OBJECT (pad, "No target pad set"); return FALSE; } gst_query_parse_caps (query, &filter); 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); result = gst_caps_from_string (KMS_AGNOSTIC_VIDEO_CAPS); break; case KMS_ELEMENT_PAD_TYPE_AUDIO: caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_AUDIO); result = gst_caps_from_string (KMS_AGNOSTIC_AUDIO_CAPS); break; default: GST_ERROR_OBJECT (pad, "unknown pad"); g_object_unref (target); return FALSE; } allowed = gst_pad_get_allowed_caps (target); /* make sure we only return results that intersect our padtemplate */ tcaps = gst_pad_get_pad_template_caps (pad); if (tcaps != NULL) { /* Update result caps */ gst_caps_unref (result); if (allowed == NULL) { result = gst_caps_ref (tcaps); } else { result = gst_caps_intersect (allowed, tcaps); } gst_caps_unref (tcaps); } else { GST_WARNING_OBJECT (pad, "Can not get capabilities from pad's template. Using agnostic's' caps"); } if (caps == NULL) { GST_ERROR_OBJECT (self, "No caps from profile"); } else { 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) { GstCaps *aux; KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); GST_ERROR_OBJECT (self, "No appsrc attached to pad %" GST_PTR_FORMAT, pad); /* Filter against profile */ GST_WARNING_OBJECT (appsrc, "Using generic profile's caps"); aux = gst_caps_intersect (caps, result); gst_caps_unref (result); result = aux; goto filter_caps; } srcpad = gst_element_get_static_pad (appsrc, "src"); KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); /* Get encodebin's caps filtering by profile */ tcaps = gst_pad_peer_query_caps (srcpad, caps); if (tcaps != NULL) { /* Filter against filtered encodebin's caps */ GstCaps *aux; aux = gst_caps_intersect (tcaps, result); gst_caps_unref (result); gst_caps_unref (tcaps); result = aux; } else if (caps != NULL) { /* Filter against profile */ GstCaps *aux; GST_WARNING_OBJECT (appsrc, "Using generic profile's caps"); aux = gst_caps_intersect (caps, result); gst_caps_unref (result); result = aux; } g_object_unref (srcpad); } filter_caps: /* filter against the query filter when needed */ if (filter != NULL) { GstCaps *aux; aux = gst_caps_intersect (result, filter); gst_caps_unref (result); result = aux; } gst_query_set_caps_result (query, result); gst_caps_unref (result); if (allowed != NULL) gst_caps_unref (allowed); if (caps != NULL) gst_caps_unref (caps); g_object_unref (target); return TRUE; }
static gboolean kms_recorder_endpoint_query_caps (KmsElement * element, GstPad * pad, GstQuery * query) { KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (element); GstCaps *allowed = NULL, *caps = NULL; GstCaps *filter, *result, *tcaps; GstElement *appsrc; gst_query_parse_caps (query, &filter); 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); allowed = kms_recorder_endpoint_allowed_caps (element, KMS_ELEMENT_PAD_TYPE_VIDEO); caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_VIDEO); result = gst_caps_from_string (KMS_AGNOSTIC_VIDEO_CAPS); break; case KMS_ELEMENT_PAD_TYPE_AUDIO: g_object_get (self->priv->mux, KMS_MUXING_PIPELINE_AUDIO_APPSRC, &appsrc, NULL); allowed = kms_recorder_endpoint_allowed_caps (element, KMS_ELEMENT_PAD_TYPE_AUDIO); caps = kms_recorder_endpoint_get_caps_from_profile (self, KMS_ELEMENT_PAD_TYPE_AUDIO); result = gst_caps_from_string (KMS_AGNOSTIC_AUDIO_CAPS); break; default: GST_ERROR_OBJECT (pad, "unknown pad"); return FALSE; } /* make sure we only return results that intersect our padtemplate */ tcaps = gst_pad_get_pad_template_caps (pad); if (tcaps != NULL) { /* Update result caps */ gst_caps_unref (result); if (allowed == NULL) { result = gst_caps_ref (tcaps); } else { result = gst_caps_intersect (allowed, tcaps); } gst_caps_unref (tcaps); } else { GST_WARNING_OBJECT (pad, "Can not get capabilities from pad's template. Using agnostic's' caps"); } if (caps == NULL) { GST_ERROR_OBJECT (self, "No caps from profile"); } else { GstPad *srcpad; /* Get encodebin's caps filtering by profile */ srcpad = gst_element_get_static_pad (appsrc, "src"); tcaps = gst_pad_peer_query_caps (srcpad, caps); if (tcaps != NULL) { /* Filter against filtered encodebin's caps */ GstCaps *aux; aux = gst_caps_intersect (tcaps, result); gst_caps_unref (result); gst_caps_unref (tcaps); result = aux; } else if (caps != NULL) { /* Filter against profile */ GstCaps *aux; GST_WARNING_OBJECT (appsrc, "Using generic profile's caps"); aux = gst_caps_intersect (caps, result); gst_caps_unref (result); result = aux; } g_object_unref (srcpad); } g_object_unref (appsrc); /* filter against the query filter when needed */ if (filter != NULL) { GstCaps *aux; aux = gst_caps_intersect (result, filter); gst_caps_unref (result); result = aux; } gst_query_set_caps_result (query, result); gst_caps_unref (result); if (allowed != NULL) gst_caps_unref (allowed); if (caps != NULL) gst_caps_unref (caps); return TRUE; }