示例#1
0
/**
 * 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));
      }
    }
  }
}
示例#5
0
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;
}
示例#7
0
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;
}
示例#9
0
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;
}