/** * gst_buffer_set_qdata: * @buffer: a #GstBuffer * @quark: name quark of data structure to set or replace * @data: (transfer full) (allow-none): a #GstStructure to store with the * buffer, name must match @quark. Can be NULL to remove an existing * structure. This function takes ownership of the structure passed. * * Set metadata structure for name quark @quark to @data, or remove the * existing metadata structure by that name in case @data is NULL. * * Takes ownership of @data. * * Since: 0.10.36 */ void gst_buffer_set_qdata (GstBuffer * buffer, GQuark quark, GstStructure * data) { GstBufferPrivate *priv; GList *l; g_return_if_fail (GST_IS_BUFFER (buffer)); g_return_if_fail (gst_buffer_is_metadata_writable (buffer)); g_return_if_fail (data == NULL || quark == gst_structure_get_name_id (data)); /* locking should not really be required, since the metadata_writable * check ensures that the caller is the only one holding a ref, so as * as a second ref is added everything turns read-only */ priv = gst_buffer_ensure_priv (buffer); if (data) { gst_structure_set_parent_refcount (data, &buffer->mini_object.refcount); } for (l = priv->qdata; l != NULL; l = l->next) { GstStructure *s = l->data; if (s->name == quark) { GST_CAT_LOG (GST_CAT_BUFFER, "Replacing qdata '%s' on buffer %p: " "%" GST_PTR_FORMAT " => %" GST_PTR_FORMAT, g_quark_to_string (quark), buffer, s, data); gst_structure_set_parent_refcount (s, NULL); gst_structure_free (s); if (data == NULL) priv->qdata = g_list_delete_link (priv->qdata, l); else l->data = data; goto done; } } GST_CAT_LOG (GST_CAT_BUFFER, "Set qdata '%s' on buffer %p: %" GST_PTR_FORMAT, g_quark_to_string (quark), buffer, data); priv->qdata = g_list_prepend (priv->qdata, data); done: return; }
/** * gst_encoding_profile_get_input_caps: * @profile: a #GstEncodingProfile * * Computes the full output caps that this @profile will be able to consume. * * Returns: (transfer full): The full caps the given @profile can consume. Call * gst_caps_unref() when you are done with the caps. */ GstCaps * gst_encoding_profile_get_input_caps (GstEncodingProfile * profile) { GstCaps *out, *tmp; GList *ltmp; GstStructure *st, *outst; GQuark out_name; guint i, len; GstCaps *fcaps; g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), NULL); if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { GstCaps *res = gst_caps_new_empty (); for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles; ltmp; ltmp = ltmp->next) { GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data; res = gst_caps_merge (res, gst_encoding_profile_get_input_caps (sprof)); } return res; } fcaps = profile->format; /* fast-path */ if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction)) return gst_caps_ref (fcaps); /* Combine the format with the restriction caps */ outst = gst_caps_get_structure (fcaps, 0); out_name = gst_structure_get_name_id (outst); tmp = gst_caps_new_empty (); len = gst_caps_get_size (profile->restriction); for (i = 0; i < len; i++) { st = gst_structure_copy (gst_caps_get_structure (profile->restriction, i)); st->name = out_name; gst_caps_append_structure (tmp, st); } out = gst_caps_intersect (tmp, fcaps); gst_caps_unref (tmp); return out; }
/* * Takes caps and copies its video fields to tmpl_caps */ static GstCaps * __gst_video_element_proxy_caps (GstElement * element, GstCaps * templ_caps, GstCaps * caps) { GstCaps *result = gst_caps_new_empty (); gint i, j; gint templ_caps_size = gst_caps_get_size (templ_caps); gint caps_size = gst_caps_get_size (caps); for (i = 0; i < templ_caps_size; i++) { GQuark q_name = gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i)); GstCapsFeatures *features = gst_caps_get_features (templ_caps, i); for (j = 0; j < caps_size; j++) { const GstStructure *caps_s = gst_caps_get_structure (caps, j); const GValue *val; GstStructure *s; GstCaps *tmp = gst_caps_new_empty (); s = gst_structure_new_id_empty (q_name); if ((val = gst_structure_get_value (caps_s, "width"))) gst_structure_set_value (s, "width", val); if ((val = gst_structure_get_value (caps_s, "height"))) gst_structure_set_value (s, "height", val); if ((val = gst_structure_get_value (caps_s, "framerate"))) gst_structure_set_value (s, "framerate", val); if ((val = gst_structure_get_value (caps_s, "pixel-aspect-ratio"))) gst_structure_set_value (s, "pixel-aspect-ratio", val); if ((val = gst_structure_get_value (caps_s, "colorimetry"))) gst_structure_set_value (s, "colorimetry", val); if ((val = gst_structure_get_value (caps_s, "chroma-site"))) gst_structure_set_value (s, "chroma-site", val); gst_caps_append_structure_full (tmp, s, gst_caps_features_copy (features)); result = gst_caps_merge (result, tmp); } } return result; }
static void do_push_event_pre (GstTracer * self, guint64 ts, GstPad * pad, GstEvent * ev) { GstPad *peer_pad = GST_PAD_PEER (pad); GstElement *parent = get_real_pad_parent (peer_pad); if (parent && (!GST_IS_BIN (parent)) && GST_OBJECT_FLAG_IS_SET (parent, GST_ELEMENT_FLAG_SINK)) { if (GST_EVENT_TYPE (ev) == GST_EVENT_CUSTOM_DOWNSTREAM) { const GstStructure *data = gst_event_get_structure (ev); if (gst_structure_get_name_id (data) == latency_probe_id) { /* store event and calculate latency when the buffer that follows * has been processed */ g_object_set_qdata ((GObject *) peer_pad, latency_probe_id, gst_event_ref (ev)); } } } }
static gboolean gst_csp_structure_is_alpha (GstStructure * s) { GQuark name; name = gst_structure_get_name_id (s); if (name == _QRAWRGB) { return gst_structure_id_has_field (s, _QALPHAMASK); } else if (name == _QRAWYUV) { guint32 fourcc; if (!gst_structure_get_fourcc (s, "format", &fourcc)) return FALSE; return (fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V')); } return FALSE; }
/* * Takes caps and copies its audio fields to tmpl_caps */ static GstCaps * __gst_audio_element_proxy_caps (GstElement * element, GstCaps * templ_caps, GstCaps * caps) { GstCaps *result = gst_caps_new_empty (); gint i, j; gint templ_caps_size = gst_caps_get_size (templ_caps); gint caps_size = gst_caps_get_size (caps); for (i = 0; i < templ_caps_size; i++) { GQuark q_name = gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i)); GstCapsFeatures *features = gst_caps_get_features (templ_caps, i); for (j = 0; j < caps_size; j++) { const GstStructure *caps_s = gst_caps_get_structure (caps, j); const GValue *val; GstStructure *s; GstCaps *tmp = gst_caps_new_empty (); s = gst_structure_new_id_empty (q_name); if ((val = gst_structure_get_value (caps_s, "rate"))) gst_structure_set_value (s, "rate", val); if ((val = gst_structure_get_value (caps_s, "channels"))) gst_structure_set_value (s, "channels", val); if ((val = gst_structure_get_value (caps_s, "channels-mask"))) gst_structure_set_value (s, "channels-mask", val); gst_caps_append_structure_full (tmp, s, gst_caps_features_copy (features)); result = gst_caps_merge (result, tmp); } } return result; }
static void gst_capsfilter_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstCapsFilter *capsfilter = GST_CAPSFILTER (object); switch (prop_id) { case PROP_FILTER_CAPS:{ GstCaps *new_caps; GstCaps *old_caps, *suggest, *nego; const GstCaps *new_caps_val = gst_value_get_caps (value); if (new_caps_val == NULL) { new_caps = gst_caps_new_any (); } else { new_caps = (GstCaps *) new_caps_val; gst_caps_ref (new_caps); } GST_OBJECT_LOCK (capsfilter); old_caps = capsfilter->filter_caps; capsfilter->filter_caps = new_caps; GST_OBJECT_UNLOCK (capsfilter); gst_caps_unref (old_caps); GST_DEBUG_OBJECT (capsfilter, "set new caps %" GST_PTR_FORMAT, new_caps); /* filter the currently negotiated format against the new caps */ GST_OBJECT_LOCK (GST_BASE_TRANSFORM_SINK_PAD (object)); nego = GST_PAD_CAPS (GST_BASE_TRANSFORM_SINK_PAD (object)); if (nego) { GST_DEBUG_OBJECT (capsfilter, "we had negotiated caps %" GST_PTR_FORMAT, nego); if (G_UNLIKELY (gst_caps_is_any (new_caps))) { GST_DEBUG_OBJECT (capsfilter, "not settings any suggestion"); suggest = NULL; } else { GstStructure *s1, *s2; /* first check if the name is the same */ s1 = gst_caps_get_structure (nego, 0); s2 = gst_caps_get_structure (new_caps, 0); if (gst_structure_get_name_id (s1) == gst_structure_get_name_id (s2)) { /* same name, copy all fields from the new caps into the previously * negotiated caps */ suggest = gst_caps_copy (nego); s1 = gst_caps_get_structure (suggest, 0); gst_structure_foreach (s2, (GstStructureForeachFunc) copy_func, s1); GST_DEBUG_OBJECT (capsfilter, "copied structure fields"); } else { GST_DEBUG_OBJECT (capsfilter, "different structure names"); /* different names, we can only suggest the complete caps */ suggest = gst_caps_copy (new_caps); } } } else { GST_DEBUG_OBJECT (capsfilter, "no negotiated caps"); /* no previous caps, the getcaps function will be used to find suitable * caps */ suggest = NULL; } GST_OBJECT_UNLOCK (GST_BASE_TRANSFORM_SINK_PAD (object)); GST_DEBUG_OBJECT (capsfilter, "suggesting new caps %" GST_PTR_FORMAT, suggest); gst_base_transform_suggest (GST_BASE_TRANSFORM (object), suggest, 0); if (suggest) gst_caps_unref (suggest); break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/* Returns TRUE if processing should stop */ static gboolean handle_message (GstDiscoverer * dc, GstMessage * msg) { gboolean done = FALSE; GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "got a %s message", GST_MESSAGE_TYPE_NAME (msg)); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR:{ GError *gerr; gchar *debug; gst_message_parse_error (msg, &gerr, &debug); GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg), "Got an error [debug:%s], [message:%s]", debug, gerr->message); dc->priv->current_error = gerr; g_free (debug); /* We need to stop */ done = TRUE; GST_DEBUG ("Setting result to ERROR"); dc->priv->current_info->result = GST_DISCOVERER_ERROR; } break; case GST_MESSAGE_EOS: GST_DEBUG ("Got EOS !"); done = TRUE; break; case GST_MESSAGE_ASYNC_DONE: if (GST_MESSAGE_SRC (msg) == (GstObject *) dc->priv->pipeline) { GST_DEBUG ("Finished changing state asynchronously"); done = TRUE; } break; case GST_MESSAGE_ELEMENT: { GQuark sttype = gst_structure_get_name_id (msg->structure); GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "structure %" GST_PTR_FORMAT, msg->structure); if (sttype == _MISSING_PLUGIN_QUARK) { GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Setting result to MISSING_PLUGINS"); dc->priv->current_info->result = GST_DISCOVERER_MISSING_PLUGINS; dc->priv->current_info->misc = gst_structure_copy (msg->structure); } else if (sttype == _STREAM_TOPOLOGY_QUARK) { dc->priv->current_topology = gst_structure_copy (msg->structure); } } break; case GST_MESSAGE_TAG: { GstTagList *tl, *tmp; gst_message_parse_tag (msg, &tl); GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Got tags %" GST_PTR_FORMAT, tl); /* Merge with current tags */ tmp = gst_tag_list_merge (dc->priv->current_info->tags, tl, GST_TAG_MERGE_APPEND); gst_tag_list_free (tl); if (dc->priv->current_info->tags) gst_tag_list_free (dc->priv->current_info->tags); dc->priv->current_info->tags = tmp; GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Current info %p, tags %" GST_PTR_FORMAT, dc->priv->current_info, tmp); } break; default: break; } return done; }
static GstCaps * gst_base_video_encoder_sink_getcaps (GstPad * pad) { GstBaseVideoEncoder *base_video_encoder; const GstCaps *templ_caps; GstCaps *allowed; GstCaps *fcaps, *filter_caps; gint i, j; base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); /* FIXME: Allow subclass to override this? */ /* Allow downstream to specify width/height/framerate/PAR constraints * and forward them upstream for video converters to handle */ templ_caps = gst_pad_get_pad_template_caps (GST_BASE_VIDEO_CODEC_SINK_PAD (base_video_encoder)); allowed = gst_pad_get_allowed_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder)); if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) { fcaps = gst_caps_copy (templ_caps); goto done; } GST_LOG_OBJECT (base_video_encoder, "template caps %" GST_PTR_FORMAT, templ_caps); GST_LOG_OBJECT (base_video_encoder, "allowed caps %" GST_PTR_FORMAT, allowed); filter_caps = gst_caps_new_empty (); for (i = 0; i < gst_caps_get_size (templ_caps); i++) { GQuark q_name = gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i)); for (j = 0; j < gst_caps_get_size (allowed); j++) { const GstStructure *allowed_s = gst_caps_get_structure (allowed, j); const GValue *val; GstStructure *s; s = gst_structure_id_empty_new (q_name); if ((val = gst_structure_get_value (allowed_s, "width"))) gst_structure_set_value (s, "width", val); if ((val = gst_structure_get_value (allowed_s, "height"))) gst_structure_set_value (s, "height", val); if ((val = gst_structure_get_value (allowed_s, "framerate"))) gst_structure_set_value (s, "framerate", val); if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio"))) gst_structure_set_value (s, "pixel-aspect-ratio", val); gst_caps_merge_structure (filter_caps, s); } } fcaps = gst_caps_intersect (filter_caps, templ_caps); gst_caps_unref (filter_caps); done: gst_caps_replace (&allowed, NULL); GST_LOG_OBJECT (base_video_encoder, "Returning caps %" GST_PTR_FORMAT, fcaps); return fcaps; }