/* GStreamer base utils library missing plugins support
 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstpbutilsmissingplugins
 * @title: Missing plugins
 * @short_description: Create, recognise and parse missing-plugins messages
 *
 * Functions to create, recognise and parse missing-plugins messages for
 * applications and elements.
 *
 * Missing-plugin messages are posted on the bus by elements like decodebin
 * or playbin if they can't find an appropriate source element or decoder
 * element. The application can use these messages for two things:
 *
 *   * concise error/problem reporting to the user mentioning what exactly
 *     is missing, see gst_missing_plugin_message_get_description()
 *
 *   * initiate installation of missing plugins, see
 *     gst_missing_plugin_message_get_installer_detail() and
 *     gst_install_plugins_async()
 *
 * Applications may also create missing-plugin messages themselves to install
 * required elements that are missing, using the install mechanism mentioned
 * above.
 *
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>            /* getpid on UNIX */
#endif
#ifdef HAVE_PROCESS_H
# include <process.h>           /* getpid on win32 */
#endif

#include "gst/gst-i18n-plugin.h"

#include "pbutils.h"
#include "pbutils-private.h"

#include <string.h>

#define GST_DETAIL_STRING_MARKER "gstreamer"

typedef enum
{
  GST_MISSING_TYPE_UNKNOWN = 0,
  GST_MISSING_TYPE_URISOURCE,
  GST_MISSING_TYPE_URISINK,
  GST_MISSING_TYPE_ELEMENT,
  GST_MISSING_TYPE_DECODER,
  GST_MISSING_TYPE_ENCODER
} GstMissingType;

static const struct
{
  GstMissingType type;
  const gchar type_string[12];
} missing_type_mapping[] = {
  {
  GST_MISSING_TYPE_URISOURCE, "urisource"}, {
  GST_MISSING_TYPE_URISINK, "urisink"}, {
  GST_MISSING_TYPE_ELEMENT, "element"}, {
  GST_MISSING_TYPE_DECODER, "decoder"}, {
  GST_MISSING_TYPE_ENCODER, "encoder"}
};

static GstMissingType
missing_structure_get_type (const GstStructure * s)
{
  const gchar *type;
  guint i;

  type = gst_structure_get_string (s, "type");
  g_return_val_if_fail (type != NULL, GST_MISSING_TYPE_UNKNOWN);

  for (i = 0; i < G_N_ELEMENTS (missing_type_mapping); ++i) {
    if (strcmp (missing_type_mapping[i].type_string, type) == 0)
      return missing_type_mapping[i].type;
  }

  return GST_MISSING_TYPE_UNKNOWN;
}

GstCaps *
copy_and_clean_caps (const GstCaps * caps)
{
  GstStructure *s;
  GstCaps *ret;

  ret = gst_caps_copy (caps);

  /* make caps easier to interpret, remove common fields that are likely
   * to be irrelevant for determining the right plugin (ie. mostly fields
   * where template caps usually have the standard MIN - MAX range as value) */
  s = gst_caps_get_structure (ret, 0);
  gst_structure_remove_field (s, "codec_data");
  gst_structure_remove_field (s, "streamheader");
  gst_structure_remove_field (s, "palette_data");
  gst_structure_remove_field (s, "pixel-aspect-ratio");
  gst_structure_remove_field (s, "framerate");
  gst_structure_remove_field (s, "leaf_size");
  gst_structure_remove_field (s, "packet_size");
  gst_structure_remove_field (s, "block_align");
  gst_structure_remove_field (s, "metadata-interval");  /* icy caps */
  /* decoders/encoders almost always handle the usual width/height/channel/rate
   * range (and if we don't remove this then the app will have a much harder
   * time blacklisting formats it has unsuccessfully tried to install before) */
  gst_structure_remove_field (s, "width");
  gst_structure_remove_field (s, "depth");
  gst_structure_remove_field (s, "height");
  gst_structure_remove_field (s, "channels");
  gst_structure_remove_field (s, "rate");
  /* parsed, framed, stream-format and alignment are going to be handled by
   * parsers and not relevant for decoders/encoders usually */
  gst_structure_remove_field (s, "parsed");
  gst_structure_remove_field (s, "framed");
  gst_structure_remove_field (s, "stream-format");
  gst_structure_remove_field (s, "alignment");
  /* rtp fields */
  gst_structure_remove_field (s, "config");
  gst_structure_remove_field (s, "clock-rate");
  gst_structure_remove_field (s, "timestamp-offset");
  gst_structure_remove_field (s, "maxps");
  gst_structure_remove_field (s, "seqnum-offset");
  gst_structure_remove_field (s, "npt-start");
  gst_structure_remove_field (s, "npt-stop");
  gst_structure_remove_field (s, "play-speed");
  gst_structure_remove_field (s, "play-scale");
  gst_structure_remove_field (s, "dynamic_range");

  return ret;
}

/**
 * gst_missing_uri_source_message_new:
 * @element: the #GstElement posting the message
 * @protocol: the URI protocol the missing source needs to implement,
 *            e.g. "http" or "mms"
 *
 * Creates a missing-plugin message for @element to notify the application
 * that a source element for a particular URI protocol is missing. This
 * function is mainly for use in plugins.
 *
 * Returns: (transfer full): a new #GstMessage, or NULL on error
 */
GstMessage *
gst_missing_uri_source_message_new (GstElement * element,
    const gchar * protocol)
{
  GstStructure *s;
  gchar *description;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (protocol != NULL, NULL);

  description = gst_pb_utils_get_source_description (protocol);

  s = gst_structure_new ("missing-plugin", "type", G_TYPE_STRING,
      "urisource", "detail", G_TYPE_STRING, protocol, "name", G_TYPE_STRING,
      description, NULL);

  g_free (description);
  return gst_message_new_element (GST_OBJECT_CAST (element), s);
}

/**
 * gst_missing_uri_sink_message_new:
 * @element: the #GstElement posting the message
 * @protocol: the URI protocol the missing sink needs to implement,
 *            e.g. "http" or "smb"
 *
 * Creates a missing-plugin message for @element to notify the application
 * that a sink element for a particular URI protocol is missing. This
 * function is mainly for use in plugins.
 *
 * Returns: (transfer full): a new #GstMessage, or NULL on error
 */
GstMessage *
gst_missing_uri_sink_message_new (GstElement * element, const gchar * protocol)
{
  GstStructure *s;
  gchar *description;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (protocol != NULL, NULL);

  description = gst_pb_utils_get_sink_description (protocol);

  s = gst_structure_new ("missing-plugin", "type", G_TYPE_STRING,
      "urisink", "detail", G_TYPE_STRING, protocol, "name", G_TYPE_STRING,
      description, NULL);

  g_free (description);
  return gst_message_new_element (GST_OBJECT_CAST (element), s);
}

/**
 * gst_missing_element_message_new:
 * @element: the #GstElement posting the message
 * @factory_name: the name of the missing element (element factory),
 *            e.g. "videoscale" or "cdparanoiasrc"
 *
 * Creates a missing-plugin message for @element to notify the application
 * that a certain required element is missing. This function is mainly for
 * use in plugins.
 *
 * Returns: (transfer full): a new #GstMessage, or NULL on error
 */
GstMessage *
gst_missing_element_message_new (GstElement * element,
    const gchar * factory_name)
{
  GstStructure *s;
  gchar *description;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (factory_name != NULL, NULL);

  description = gst_pb_utils_get_element_description (factory_name);

  s = gst_structure_new ("missing-plugin", "type", G_TYPE_STRING,
      "element", "detail", G_TYPE_STRING, factory_name, "name", G_TYPE_STRING,
      description, NULL);

  g_free (description);
  return gst_message_new_element (GST_OBJECT_CAST (element), s);
}

/**
 * gst_missing_decoder_message_new:
 * @element: the #GstElement posting the message
 * @decode_caps: the (fixed) caps for which a decoder element is needed
 *
 * Creates a missing-plugin message for @element to notify the application
 * that a decoder element for a particular set of (fixed) caps is missing.
 * This function is mainly for use in plugins.
 *
 * Returns: (transfer full): a new #GstMessage, or NULL on error
 */
GstMessage *
gst_missing_decoder_message_new (GstElement * element,
    const GstCaps * decode_caps)
{
  GstStructure *s;
  GstCaps *caps;
  gchar *description;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (decode_caps != NULL, NULL);
  g_return_val_if_fail (GST_IS_CAPS (decode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_any (decode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_empty (decode_caps), NULL);
  g_return_val_if_fail (gst_caps_is_fixed (decode_caps), NULL);

  description = gst_pb_utils_get_decoder_description (decode_caps);
  caps = copy_and_clean_caps (decode_caps);

  s = gst_structure_new ("missing-plugin", "type", G_TYPE_STRING,
      "decoder", "detail", GST_TYPE_CAPS, caps, "name", G_TYPE_STRING,
      description, NULL);

  gst_caps_unref (caps);
  g_free (description);

  return gst_message_new_element (GST_OBJECT_CAST (element), s);
}

/**
 * gst_missing_encoder_message_new:
 * @element: the #GstElement posting the message
 * @encode_caps: the (fixed) caps for which an encoder element is needed
 *
 * Creates a missing-plugin message for @element to notify the application
 * that an encoder element for a particular set of (fixed) caps is missing.
 * This function is mainly for use in plugins.
 *
 * Returns: (transfer full): a new #GstMessage, or NULL on error
 */
GstMessage *
gst_missing_encoder_message_new (GstElement * element,
    const GstCaps * encode_caps)
{
  GstStructure *s;
  GstCaps *caps;
  gchar *description;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (encode_caps != NULL, NULL);
  g_return_val_if_fail (GST_IS_CAPS (encode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_any (encode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_empty (encode_caps), NULL);
  g_return_val_if_fail (gst_caps_is_fixed (encode_caps), NULL);

  description = gst_pb_utils_get_encoder_description (encode_caps);
  caps = copy_and_clean_caps (encode_caps);

  s = gst_structure_new ("missing-plugin", "type", G_TYPE_STRING,
      "encoder", "detail", GST_TYPE_CAPS, caps, "name", G_TYPE_STRING,
      description, NULL);

  gst_caps_unref (caps);
  g_free (description);

  return gst_message_new_element (GST_OBJECT_CAST (element), s);
}

static gboolean
missing_structure_get_string_detail (const GstStructure * s, gchar ** p_detail)
{
  const gchar *detail;
  GType detail_type;

  *p_detail = NULL;

  detail_type = gst_structure_get_field_type (s, "detail");
  if (!g_type_is_a (detail_type, G_TYPE_STRING)) {
    GST_WARNING ("expected 'detail' field to be of G_TYPE_STRING");
    return FALSE;
  }

  detail = gst_structure_get_string (s, "detail");
  if (detail == NULL || *detail == '\0') {
    GST_WARNING ("empty 'detail' field");
    return FALSE;
  }
  *p_detail = g_strdup (detail);
  return TRUE;
}

static gboolean
missing_structure_get_caps_detail (const GstStructure * s, GstCaps ** p_caps)
{
  const GstCaps *caps;
  const GValue *val;
  GType detail_type;

  *p_caps = NULL;

  detail_type = gst_structure_get_field_type (s, "detail");
  if (!g_type_is_a (detail_type, GST_TYPE_CAPS)) {
    GST_WARNING ("expected 'detail' field to be of GST_TYPE_CAPS");
    return FALSE;
  }

  val = gst_structure_get_value (s, "detail");
  caps = gst_value_get_caps (val);
  if (gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
    GST_WARNING ("EMPTY or ANY caps not allowed");
    return FALSE;
  }

  *p_caps = gst_caps_copy (caps);
  return TRUE;
}

/**
 * gst_missing_plugin_message_get_installer_detail:
 * @msg: a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_plugin_message_get_installer_detail (GstMessage * msg)
{
  GstMissingType missing_type;
  const gchar *progname;
  const gchar *type;
  GString *str = NULL;
  gchar *detail = NULL;
  gchar *desc;
  const GstStructure *structure;

  g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL);

  structure = gst_message_get_structure (msg);
  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, structure);

  missing_type = missing_structure_get_type (structure);
  if (missing_type == GST_MISSING_TYPE_UNKNOWN) {
    GST_WARNING ("couldn't parse 'type' field");
    goto error;
  }

  type = gst_structure_get_string (structure, "type");
  g_assert (type != NULL);      /* validity already checked above */

  /* FIXME: use gst_installer_detail_new() here too */
  str = g_string_new (GST_DETAIL_STRING_MARKER "|");
  g_string_append_printf (str, "%s|", GST_API_VERSION);

  progname = (const gchar *) g_get_prgname ();
  if (progname) {
    g_string_append_printf (str, "%s|", progname);
  } else {
    g_string_append_printf (str, "pid/%lu|", (gulong) getpid ());
  }

  desc = gst_missing_plugin_message_get_description (msg);
  if (desc) {
    g_strdelimit (desc, "|", '#');
    g_string_append_printf (str, "%s|", desc);
    g_free (desc);
  } else {
    g_string_append (str, "|");
  }

  switch (missing_type) {
    case GST_MISSING_TYPE_URISOURCE:
    case GST_MISSING_TYPE_URISINK:
    case GST_MISSING_TYPE_ELEMENT:
      if (!missing_structure_get_string_detail (structure, &detail))
        goto error;
      break;
    case GST_MISSING_TYPE_DECODER:
    case GST_MISSING_TYPE_ENCODER:{
      GstCaps *caps = NULL;

      if (!missing_structure_get_caps_detail (structure, &caps))
        goto error;

      detail = gst_caps_to_string (caps);
      gst_caps_unref (caps);
      break;
    }
    default:
      g_return_val_if_reached (NULL);
  }

  g_string_append_printf (str, "%s-%s", type, detail);
  g_free (detail);

  return g_string_free (str, FALSE);

/* ERRORS */
error:
  {
    GST_WARNING ("Failed to parse missing-plugin msg: %" GST_PTR_FORMAT, msg);
    if (str)
      g_string_free (str, TRUE);
    return NULL;
  }
}

/**
 * gst_missing_plugin_message_get_description:
 * @msg: a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT
 *
 * Returns a localised string describing the missing feature, for use in
 * error dialogs and the like. Should never return NULL unless @msg is not
 * a valid missing-plugin message.
 *
 * This function is mainly for applications that need a human-readable string
 * describing a missing plugin, given a previously collected missing-plugin
 * message
 *
 * Returns: a newly-allocated description string, or NULL on error. Free
 *          string with g_free() when not needed any longer.
 */
gchar *
gst_missing_plugin_message_get_description (GstMessage * msg)
{
  GstMissingType missing_type;
  const gchar *desc;
  gchar *ret = NULL;
  const GstStructure *structure;

  g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL);

  structure = gst_message_get_structure (msg);
  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, structure);

  desc = gst_structure_get_string (structure, "name");
  if (desc != NULL && *desc != '\0') {
    ret = g_strdup (desc);
    goto done;
  }

  /* fallback #1 */
  missing_type = missing_structure_get_type (structure);

  switch (missing_type) {
    case GST_MISSING_TYPE_URISOURCE:
    case GST_MISSING_TYPE_URISINK:
    case GST_MISSING_TYPE_ELEMENT:{
      gchar *detail = NULL;

      if (missing_structure_get_string_detail (structure, &detail)) {
        if (missing_type == GST_MISSING_TYPE_URISOURCE)
          ret = gst_pb_utils_get_source_description (detail);
        else if (missing_type == GST_MISSING_TYPE_URISINK)
          ret = gst_pb_utils_get_sink_description (detail);
        else
          ret = gst_pb_utils_get_element_description (detail);
        g_free (detail);
      }
      break;
    }
    case GST_MISSING_TYPE_DECODER:
    case GST_MISSING_TYPE_ENCODER:{
      GstCaps *caps = NULL;

      if (missing_structure_get_caps_detail (structure, &caps)) {
        if (missing_type == GST_MISSING_TYPE_DECODER)
          ret = gst_pb_utils_get_decoder_description (caps);
        else
          ret = gst_pb_utils_get_encoder_description (caps);
        gst_caps_unref (caps);
      }
      break;
    }
    default:
      break;
  }

  if (ret)
    goto done;

  /* fallback #2 */
  switch (missing_type) {
    case GST_MISSING_TYPE_URISOURCE:
      desc = _("Unknown source element");
      break;
    case GST_MISSING_TYPE_URISINK:
      desc = _("Unknown sink element");
      break;
    case GST_MISSING_TYPE_ELEMENT:
      desc = _("Unknown element");
      break;
    case GST_MISSING_TYPE_DECODER:
      desc = _("Unknown decoder element");
      break;
    case GST_MISSING_TYPE_ENCODER:
      desc = _("Unknown encoder element");
      break;
    default:
      /* we should really never get here, but we better still return
       * something if we do */
      desc = _("Plugin or element of unknown type");
      break;
  }
  ret = g_strdup (desc);

done:

  GST_LOG ("returning '%s'", ret);
  return ret;
}

/**
 * gst_is_missing_plugin_message:
 * @msg: a #GstMessage
 *
 * Checks whether @msg is a missing plugins message.
 *
 * Returns: %TRUE if @msg is a missing-plugins message, otherwise %FALSE.
 */
gboolean
gst_is_missing_plugin_message (GstMessage * msg)
{
  const GstStructure *structure;

  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (GST_IS_MESSAGE (msg), FALSE);

  structure = gst_message_get_structure (msg);
  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || structure == NULL)
    return FALSE;

  return gst_structure_has_name (structure, "missing-plugin");
}

/* takes ownership of the description */
static gchar *
gst_installer_detail_new (gchar * description, const gchar * type,
    const gchar * detail)
{
  const gchar *progname;
  GString *s;

  s = g_string_new (GST_DETAIL_STRING_MARKER "|");
  g_string_append_printf (s, "%s|", GST_API_VERSION);

  progname = (const gchar *) g_get_prgname ();
  if (progname) {
    g_string_append_printf (s, "%s|", progname);
  } else {
    g_string_append_printf (s, "pid/%lu|", (gulong) getpid ());
  }

  if (description) {
    g_strdelimit (description, "|", '#');
    g_string_append_printf (s, "%s|", description);
    g_free (description);
  } else {
    g_string_append (s, "|");
  }

  g_string_append_printf (s, "%s-%s", type, detail);

  return g_string_free (s, FALSE);
}

/**
 * gst_missing_uri_source_installer_detail_new:
 * @protocol: the URI protocol the missing source needs to implement,
 *            e.g. "http" or "mms"
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions in
 * the case where the application knows exactly what kind of plugin it is
 * missing.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_uri_source_installer_detail_new (const gchar * protocol)
{
  gchar *desc;

  g_return_val_if_fail (protocol != NULL, NULL);

  desc = gst_pb_utils_get_source_description (protocol);
  return gst_installer_detail_new (desc, "urisource", protocol);
}

/**
 * gst_missing_uri_sink_installer_detail_new:
 * @protocol: the URI protocol the missing source needs to implement,
 *            e.g. "http" or "mms"
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions in
 * the case where the application knows exactly what kind of plugin it is
 * missing.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_uri_sink_installer_detail_new (const gchar * protocol)
{
  gchar *desc;

  g_return_val_if_fail (protocol != NULL, NULL);

  desc = gst_pb_utils_get_sink_description (protocol);
  return gst_installer_detail_new (desc, "urisink", protocol);
}

/**
 * gst_missing_element_installer_detail_new:
 * @factory_name: the name of the missing element (element factory),
 *            e.g. "videoscale" or "cdparanoiasrc"
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions in
 * the case where the application knows exactly what kind of plugin it is
 * missing.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_element_installer_detail_new (const gchar * factory_name)
{
  gchar *desc;

  g_return_val_if_fail (factory_name != NULL, NULL);

  desc = gst_pb_utils_get_element_description (factory_name);
  return gst_installer_detail_new (desc, "element", factory_name);
}

/**
 * gst_missing_decoder_installer_detail_new:
 * @decode_caps: the (fixed) caps for which a decoder element is needed
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions in
 * the case where the application knows exactly what kind of plugin it is
 * missing.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_decoder_installer_detail_new (const GstCaps * decode_caps)
{
  GstCaps *caps;
  gchar *detail_str, *caps_str, *desc;

  g_return_val_if_fail (decode_caps != NULL, NULL);
  g_return_val_if_fail (GST_IS_CAPS (decode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_any (decode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_empty (decode_caps), NULL);
  g_return_val_if_fail (gst_caps_is_fixed (decode_caps), NULL);

  desc = gst_pb_utils_get_decoder_description (decode_caps);
  caps = copy_and_clean_caps (decode_caps);
  caps_str = gst_caps_to_string (caps);
  detail_str = gst_installer_detail_new (desc, "decoder", caps_str);
  g_free (caps_str);
  gst_caps_unref (caps);

  return detail_str;
}

/**
 * gst_missing_encoder_installer_detail_new:
 * @encode_caps: the (fixed) caps for which an encoder element is needed
 *
 * Returns an opaque string containing all the details about the missing
 * element to be passed to an external installer called via
 * gst_install_plugins_async() or gst_install_plugins_sync().
 *
 * This function is mainly for applications that call external plugin
 * installation mechanisms using one of the two above-mentioned functions in
 * the case where the application knows exactly what kind of plugin it is
 * missing.
 *
 * Returns: a newly-allocated detail string, or NULL on error. Free string
 *          with g_free() when not needed any longer.
 */
gchar *
gst_missing_encoder_installer_detail_new (const GstCaps * encode_caps)
{
  GstCaps *caps;
  gchar *detail_str, *caps_str, *desc;

  g_return_val_if_fail (encode_caps != NULL, NULL);
  g_return_val_if_fail (GST_IS_CAPS (encode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_any (encode_caps), NULL);
  g_return_val_if_fail (!gst_caps_is_empty (encode_caps), NULL);
  g_return_val_if_fail (gst_caps_is_fixed (encode_caps), NULL);

  desc = gst_pb_utils_get_encoder_description (encode_caps);
  caps = copy_and_clean_caps (encode_caps);
  caps_str = gst_caps_to_string (caps);
  detail_str = gst_installer_detail_new (desc, "encoder", caps_str);
  g_free (caps_str);
  gst_caps_unref (caps);

  return detail_str;
}
