static GstEncodingProfile *
make_profile_from_info (GstDiscovererInfo * info)
{
  GstEncodingContainerProfile *profile = NULL;
  GstDiscovererStreamInfo *sinfo = gst_discoverer_info_get_stream_info (info);

  /* Get the container format */
  if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
    GList *tmp, *substreams;

    profile = gst_encoding_container_profile_new ((gchar *) "concatenate", NULL,
        gst_discoverer_stream_info_get_caps (sinfo), NULL);

    substreams =
        gst_discoverer_container_info_get_streams ((GstDiscovererContainerInfo
            *) sinfo);

    /* For each on the formats add stream profiles */
    for (tmp = substreams; tmp; tmp = tmp->next) {
      GstDiscovererStreamInfo *stream = GST_DISCOVERER_STREAM_INFO (tmp->data);
      GstEncodingProfile *sprof = NULL;

      if (GST_IS_DISCOVERER_VIDEO_INFO (stream)) {
        sprof = (GstEncodingProfile *)
            gst_encoding_video_profile_new (gst_discoverer_stream_info_get_caps
            (stream), NULL, NULL, 1);
      } else if (GST_IS_DISCOVERER_AUDIO_INFO (stream)) {
        sprof = (GstEncodingProfile *)
            gst_encoding_audio_profile_new (gst_discoverer_stream_info_get_caps
            (stream), NULL, NULL, 1);
      } else {
        GST_WARNING ("Unsupported streams");
      }

      if (sprof)
        gst_encoding_container_profile_add_profile (profile, sprof);
    }
    if (substreams)
      gst_discoverer_stream_info_list_free (substreams);
  } else {
    GST_ERROR ("No container format !!!");
  }

  if (sinfo)
    gst_discoverer_stream_info_unref (sinfo);

  return GST_ENCODING_PROFILE (profile);
}
示例#2
0
static GstCaps *
caps_from_audio_stream_info (GstDiscovererStreamInfo *info)
{
        GstCaps *temp = gst_discoverer_stream_info_get_caps (info);
        GstCaps *caps = gst_caps_copy (temp);
        const GstDiscovererAudioInfo *audio_info =
                GST_DISCOVERER_AUDIO_INFO(info);
        guint data;

        gst_caps_unref (temp);

        data = gst_discoverer_audio_info_get_sample_rate (audio_info);
        if (data)
                gst_caps_set_simple (caps, "rate", G_TYPE_INT, data, NULL);

        data = gst_discoverer_audio_info_get_channels (audio_info);
        if (data)
                gst_caps_set_simple (caps, "channels", G_TYPE_INT, data, NULL);

        data = gst_discoverer_audio_info_get_bitrate (audio_info);
        if (data)
                gst_caps_set_simple (caps, "bitrate", G_TYPE_INT, data, NULL);

        data = gst_discoverer_audio_info_get_max_bitrate (audio_info);
        if (data)
                gst_caps_set_simple
                        (caps, "maximum-bitrate", G_TYPE_INT, data, NULL);

        data = gst_discoverer_audio_info_get_depth (audio_info);
        if (data)
                gst_caps_set_simple (caps, "depth", G_TYPE_INT, data, NULL);

        return caps;
}
示例#3
0
/* Print information regarding a stream */
void print_stream_info (GstDiscovererStreamInfo *info, gint depth) {
  gchar *desc = NULL;
  GstCaps *caps;
  const GstTagList *tags;
   
  caps = gst_discoverer_stream_info_get_caps (info);
   
  if (caps) {
    if (gst_caps_is_fixed (caps))
      desc = gst_pb_utils_get_codec_description (caps);
    else
      desc = gst_caps_to_string (caps);
    gst_caps_unref (caps);
  }
   
  g_print ("%*s%s: %s\n", 2 * depth, " ", gst_discoverer_stream_info_get_stream_type_nick (info), (desc ? desc : ""));
   
  if (desc) {
    g_free (desc);
    desc = NULL;
  }
   
  tags = gst_discoverer_stream_info_get_tags (info);
  if (tags) {
    g_print ("%*sTags:\n", 2 * (depth + 1), " ");
    gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (depth + 2));
  }
}
static void
gst_stream_information_to_string (GstDiscovererStreamInfo * info, GString * s,
    guint depth)
{
  gchar *tmp;
  GstCaps *caps;
  const GstStructure *misc;

  my_g_string_append_printf (s, depth, "Codec:\n");
  caps = gst_discoverer_stream_info_get_caps (info);
  tmp = gst_caps_to_string (caps);
  gst_caps_unref (caps);
  my_g_string_append_printf (s, depth, "  %s\n", tmp);
  g_free (tmp);

  my_g_string_append_printf (s, depth, "Additional info:\n");
  if ((misc = gst_discoverer_stream_info_get_misc (info))) {
    tmp = gst_structure_to_string (misc);
    my_g_string_append_printf (s, depth, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, depth, "  None\n");
  }

  my_g_string_append_printf (s, depth, "Stream ID: %s\n",
      gst_discoverer_stream_info_get_stream_id (info));
}
示例#5
0
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 GstElement *
ges_multi_file_source_create_source (GESTrackElement * track_element)
{
  GESMultiFileSource *self;
  GstElement *bin, *src, *decodebin;
  GstCaps *disc_caps;
  GstDiscovererStreamInfo *stream_info;
  GValue fps = G_VALUE_INIT;
  GstCaps *caps;
  GESUriSourceAsset *asset;
  GESMultiFileURI *uri_data;

  self = (GESMultiFileSource *) track_element;

  asset =
      GES_URI_SOURCE_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (self)));

  if (asset != NULL) {
    stream_info = ges_uri_source_asset_get_stream_info (asset);
    g_assert (stream_info);
    disc_caps = gst_discoverer_stream_info_get_caps (stream_info);
    caps = gst_caps_copy (disc_caps);
    GST_DEBUG ("Got some nice caps %s", gst_caps_to_string (disc_caps));
    gst_object_unref (stream_info);
    gst_caps_unref (disc_caps);
  } else {
    caps = gst_caps_new_empty ();
    GST_WARNING ("Could not extract asset.");
  }

  g_value_init (&fps, GST_TYPE_FRACTION);
  gst_value_set_fraction (&fps, 25, 1);
  gst_caps_set_value (caps, "framerate", &fps);

  bin = GST_ELEMENT (gst_bin_new ("multi-image-bin"));
  src = gst_element_factory_make ("multifilesrc", NULL);

  uri_data = ges_multi_file_uri_new (self->uri);
  g_object_set (src, "start-index", uri_data->start, "stop-index",
      uri_data->end, "caps", caps, "location", uri_data->location, NULL);
  g_free (uri_data);

  decodebin = gst_element_factory_make ("decodebin", NULL);

  gst_bin_add_many (GST_BIN (bin), src, decodebin, NULL);
  gst_element_link_pads_full (src, "src", decodebin, "sink",
      GST_PAD_LINK_CHECK_NOTHING);

  g_signal_connect (G_OBJECT (decodebin), "pad-added",
      G_CALLBACK (pad_added_cb), bin);

  return bin;
}
static GstCaps *
get_caps (GUPnPDLNAGstImageInformation *gst_info)
{
    GUPnPDLNAGstImageInformationPrivate *priv = gst_info->priv;

    if (!priv->caps)
        priv->caps = gst_discoverer_stream_info_get_caps
                     (GST_DISCOVERER_STREAM_INFO
                      (get_image_info (gst_info)));

    return priv->caps;
}
static gchar *
gst_stream_subtitle_information_to_string (GstDiscovererStreamInfo * info,
    gint depth)
{
  GstDiscovererSubtitleInfo *subtitle_info;
  GString *s;
  gchar *tmp;
  const gchar *ctmp;
  int len = 400;
  const GstTagList *tags;
  GstCaps *caps;

  g_return_val_if_fail (info != NULL, NULL);

  s = g_string_sized_new (len);

  my_g_string_append_printf (s, depth, "Codec:\n");
  caps = gst_discoverer_stream_info_get_caps (info);
  tmp = gst_caps_to_string (caps);
  gst_caps_unref (caps);
  my_g_string_append_printf (s, depth, "  %s\n", tmp);
  g_free (tmp);

  my_g_string_append_printf (s, depth, "Additional info:\n");
  if (gst_discoverer_stream_info_get_misc (info)) {
    tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info));
    my_g_string_append_printf (s, depth, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, depth, "  None\n");
  }

  subtitle_info = (GstDiscovererSubtitleInfo *) info;
  ctmp = gst_discoverer_subtitle_info_get_language (subtitle_info);
  my_g_string_append_printf (s, depth, "Language: %s\n",
      ctmp ? ctmp : "<unknown>");

  my_g_string_append_printf (s, depth, "Tags:\n");
  tags = gst_discoverer_stream_info_get_tags (info);
  if (tags) {
    tmp = gst_structure_to_string ((GstStructure *) tags);
    my_g_string_append_printf (s, depth, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, depth, "  None\n");
  }
  if (verbose)
    my_g_string_append_printf (s, depth, "\n");

  return g_string_free (s, FALSE);
}
/**
 * gst_encoding_profile_from_discoverer:
 * @info: (transfer none): The #GstDiscovererInfo to read from
 *
 * Creates a #GstEncodingProfile matching the formats from the given
 * #GstDiscovererInfo. Streams other than audio or video (eg,
 * subtitles), are currently ignored.
 *
 * Returns: (transfer full): The new #GstEncodingProfile or %NULL.
 */
GstEncodingProfile *
gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
{
  GstEncodingContainerProfile *profile;
  GstDiscovererStreamInfo *sinfo;
  GList *streams, *stream;
  GstCaps *caps = NULL;
  guint n_streams = 0;

  if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK)
    return NULL;

  sinfo = gst_discoverer_info_get_stream_info (info);
  if (!sinfo)
    return NULL;

  caps = gst_discoverer_stream_info_get_caps (sinfo);
  GST_LOG ("Container: %" GST_PTR_FORMAT "\n", caps);
  profile =
      gst_encoding_container_profile_new ("auto-generated",
      "Automatically generated from GstDiscovererInfo", caps, NULL);
  gst_caps_unref (caps);
  if (!profile) {
    GST_ERROR ("Failed to create container profile from caps %" GST_PTR_FORMAT,
        caps);
    return NULL;
  }

  streams =
      gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
      (sinfo));
  for (stream = streams; stream; stream = stream->next) {
    if (add_stream_to_profile (profile,
            (GstDiscovererStreamInfo *) stream->data))
      n_streams++;
  }
  gst_discoverer_stream_info_list_free (streams);

  if (n_streams == 0) {
    GST_ERROR ("Failed to add any streams");
    g_object_unref (profile);
    return NULL;
  }

  return (GstEncodingProfile *) profile;
}
示例#10
0
static void
print_stream_info (GstDiscovererStreamInfo * info, void *depth)
{
  gchar *desc = NULL;
  GstCaps *caps;

  caps = gst_discoverer_stream_info_get_caps (info);

  if (caps) {
    if (gst_caps_is_fixed (caps) && !verbose)
      desc = gst_pb_utils_get_codec_description (caps);
    else
      desc = gst_caps_to_string (caps);
    gst_caps_unref (caps);
  }

  g_print ("%*s%s: %s\n", 2 * GPOINTER_TO_INT (depth), " ",
      gst_discoverer_stream_info_get_stream_type_nick (info), desc);

  if (desc) {
    g_free (desc);
    desc = NULL;
  }

  if (verbose) {
    if (GST_IS_DISCOVERER_AUDIO_INFO (info))
      desc =
          gst_stream_audio_information_to_string (info,
          GPOINTER_TO_INT (depth) + 1);
    else if (GST_IS_DISCOVERER_VIDEO_INFO (info))
      desc =
          gst_stream_video_information_to_string (info,
          GPOINTER_TO_INT (depth) + 1);
    else if (GST_IS_DISCOVERER_SUBTITLE_INFO (info))
      desc =
          gst_stream_subtitle_information_to_string (info,
          GPOINTER_TO_INT (depth) + 1);
    if (desc) {
      g_print ("%s", desc);
      g_free (desc);
    }
  }
}
static GstValidateStreamInfo *
gst_validate_stream_info_from_discoverer_info (GstDiscovererStreamInfo * info)
{
  GstValidateStreamInfo *ret = g_new0 (GstValidateStreamInfo, 1);

  ret->caps = gst_discoverer_stream_info_get_caps (info);
  if (GST_IS_DISCOVERER_CONTAINER_INFO (info)) {
    GList *streams =
        gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
        (info));
    GList *iter;

    for (iter = streams; iter; iter = g_list_next (iter)) {
      ret->children = g_list_append (ret->children,
          gst_validate_stream_info_from_discoverer_info (iter->data));
    }
    gst_discoverer_stream_info_list_free (streams);
  }

  return ret;
}
示例#12
0
gchar *
lgm_filename_to_uri (const gchar *filename)
{
  gchar *uri, *path;
  GError *err = NULL;

#ifdef G_OS_WIN32
  if (g_path_is_absolute(filename) || !gst_uri_is_valid (filename)) {
#else
  if (!gst_uri_is_valid (filename)) {
#endif
    if (!g_path_is_absolute (filename)) {
      gchar *cur_dir;

      cur_dir = g_get_current_dir ();
      path = g_build_filename (cur_dir, filename, NULL);
      g_free (cur_dir);
    } else {
      path = g_strdup (filename);
    }

    uri = g_filename_to_uri (path, NULL, &err);
    g_free (path);
    path = NULL;

    if (err != NULL) {
      g_error_free (err);
      return NULL;
    }
  } else {
    uri = g_strdup (filename);
  }
  return uri;
}

GstDiscovererResult
lgm_discover_uri (
    const gchar *filename, guint64 *duration, guint *width,
    guint *height, guint *fps_n, guint *fps_d, guint *par_n, guint *par_d,
    gchar **container, gchar **video_codec, gchar **audio_codec,
    GError **err)
{
  GstDiscoverer *discoverer;
  GstDiscovererInfo *info;
  GList *videos = NULL, *audios = NULL;
  GstDiscovererStreamInfo *sinfo = NULL;
  GstDiscovererVideoInfo *vinfo = NULL;
  GstDiscovererAudioInfo *ainfo = NULL;
  GstDiscovererResult ret;
  gchar *uri;

  uri = lgm_filename_to_uri (filename);
  if (uri == NULL) {
    return GST_DISCOVERER_URI_INVALID;
  }

  *duration = *width = *height = *fps_n = *fps_d = *par_n = *par_d = 0;
  *container = *audio_codec = *video_codec = NULL;

  discoverer = gst_discoverer_new (4 * GST_SECOND, err);
  if (*err != NULL) {
    g_free (uri);
    return GST_DISCOVERER_ERROR;
  }

  info = gst_discoverer_discover_uri (discoverer, uri, err);
  g_free (uri);
  if (*err != NULL) {
    if (info != NULL) {
      return gst_discoverer_info_get_result (info);
    } else {
      return GST_DISCOVERER_ERROR;
    }
  }

  sinfo = gst_discoverer_info_get_stream_info (info);
  *duration = gst_discoverer_info_get_duration (info);

  if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
    GstCaps *caps;

    caps = gst_discoverer_stream_info_get_caps (
        GST_DISCOVERER_STREAM_INFO(sinfo));
    *container = gst_pb_utils_get_codec_description (caps);
    gst_caps_unref (caps);
  }

  if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
    ainfo = GST_DISCOVERER_AUDIO_INFO (sinfo);
  } else {
    audios = gst_discoverer_info_get_audio_streams (info);
    if (audios != NULL) {
      ainfo = audios->data;
    }
  }

  if (ainfo != NULL) {
    GstCaps *caps;

    caps = gst_discoverer_stream_info_get_caps (
        GST_DISCOVERER_STREAM_INFO (ainfo));
    *audio_codec = gst_pb_utils_get_codec_description (caps);
    gst_caps_unref (caps);
  }
  if (audios != NULL) {
    gst_discoverer_stream_info_list_free (audios);
  }

  if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
    vinfo = GST_DISCOVERER_VIDEO_INFO (sinfo);
  } else {
    videos = gst_discoverer_info_get_video_streams (info);
    if (videos != NULL) {
      vinfo = videos->data;
    }
  }

  if (vinfo != NULL) {
    GstCaps *caps;

    caps = gst_discoverer_stream_info_get_caps (
        GST_DISCOVERER_STREAM_INFO (vinfo));
    *video_codec = gst_pb_utils_get_codec_description (caps);
    gst_caps_unref (caps);
    *height = gst_discoverer_video_info_get_height (vinfo);
    *width = gst_discoverer_video_info_get_width (vinfo);
    *fps_n = gst_discoverer_video_info_get_framerate_num (vinfo);
    *fps_d = gst_discoverer_video_info_get_framerate_denom (vinfo);
    *par_n = gst_discoverer_video_info_get_par_num (vinfo);
    *par_d = gst_discoverer_video_info_get_par_denom (vinfo);
  }
  if (videos != NULL) {
    gst_discoverer_stream_info_list_free (videos);
  }

  ret = gst_discoverer_info_get_result (info);
  gst_discoverer_info_unref (info);
  g_object_unref (discoverer);

  return ret;
}
示例#13
0
static gchar *
gst_stream_video_information_to_string (GstDiscovererStreamInfo * info,
    gint depth)
{
  GstDiscovererVideoInfo *video_info;
  GString *s;
  gchar *tmp;
  int len = 500;
  const GstStructure *misc;
  const GstTagList *tags;
  GstCaps *caps;

  g_return_val_if_fail (info != NULL, NULL);

  s = g_string_sized_new (len);

  my_g_string_append_printf (s, "Codec:\n");
  caps = gst_discoverer_stream_info_get_caps (info);
  tmp = gst_caps_to_string (caps);
  gst_caps_unref (caps);
  my_g_string_append_printf (s, "  %s\n", tmp);
  g_free (tmp);

  my_g_string_append_printf (s, "Additional info:\n");
  misc = gst_discoverer_stream_info_get_misc (info);
  if (misc) {
    tmp = gst_structure_to_string (misc);
    my_g_string_append_printf (s, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, "  None\n");
  }

  video_info = (GstDiscovererVideoInfo *) info;
  my_g_string_append_printf (s, "Width: %u\n",
      gst_discoverer_video_info_get_width (video_info));
  my_g_string_append_printf (s, "Height: %u\n",
      gst_discoverer_video_info_get_height (video_info));
  my_g_string_append_printf (s, "Depth: %u\n",
      gst_discoverer_video_info_get_depth (video_info));

  my_g_string_append_printf (s, "Frame rate: %u/%u\n",
      gst_discoverer_video_info_get_framerate_num (video_info),
      gst_discoverer_video_info_get_framerate_denom (video_info));

  my_g_string_append_printf (s, "Pixel aspect ratio: %u/%u\n",
      gst_discoverer_video_info_get_par_num (video_info),
      gst_discoverer_video_info_get_par_denom (video_info));

  my_g_string_append_printf (s, "Interlaced: %s\n",
      gst_discoverer_video_info_is_interlaced (video_info) ? "true" : "false");

  my_g_string_append_printf (s, "Bitrate: %u\n",
      gst_discoverer_video_info_get_bitrate (video_info));
  my_g_string_append_printf (s, "Max bitrate: %u\n",
      gst_discoverer_video_info_get_max_bitrate (video_info));

  my_g_string_append_printf (s, "Tags:\n");
  tags = gst_discoverer_stream_info_get_tags (info);
  if (tags) {
    tmp = gst_structure_to_string ((GstStructure *) tags);
    my_g_string_append_printf (s, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, "  None\n");
  }
  if (verbose)
    my_g_string_append_printf (s, "\n");

  return g_string_free (s, FALSE);
}
示例#14
0
static GstCaps *
caps_from_video_stream_info (GstDiscovererStreamInfo *info)
{
        GstCaps *temp = gst_discoverer_stream_info_get_caps (info);
        GstCaps *caps = gst_caps_copy (temp);
        const GstDiscovererVideoInfo *video_info =
                GST_DISCOVERER_VIDEO_INFO (info);
        const GstTagList *stream_tag_list;
        guint n, d, data;
        gboolean value;

        gst_caps_unref (temp);

        data = gst_discoverer_video_info_get_height (video_info);
        if (data)
                gst_caps_set_simple (caps, "height", G_TYPE_INT, data, NULL);

        data = gst_discoverer_video_info_get_width (video_info);
        if (data)
                gst_caps_set_simple (caps, "width", G_TYPE_INT, data, NULL);

        data = gst_discoverer_video_info_get_depth (video_info);
        if (data)
                gst_caps_set_simple (caps, "depth", G_TYPE_INT, data, NULL);

        n = gst_discoverer_video_info_get_framerate_num (video_info);
        d = gst_discoverer_video_info_get_framerate_denom (video_info);
        if (n && d)
                gst_caps_set_simple (caps,
                                     "framerate",
                                     GST_TYPE_FRACTION, n, d,
                                     NULL);

        n = gst_discoverer_video_info_get_par_num (video_info);
        d = gst_discoverer_video_info_get_par_denom (video_info);
        if (n && d)
                gst_caps_set_simple (caps,
                                     "pixel-aspect-ratio",
                                     GST_TYPE_FRACTION, n, d,
                                     NULL);

        value = gst_discoverer_video_info_is_interlaced (video_info);
        if (value)
                gst_caps_set_simple
                        (caps, "interlaced", G_TYPE_BOOLEAN, value, NULL);

        stream_tag_list = gst_discoverer_stream_info_get_tags (info);
        if (stream_tag_list) {
                guint bitrate;
                if (gst_tag_list_get_uint (stream_tag_list, "bitrate", &bitrate))
                        gst_caps_set_simple
                             (caps, "bitrate", G_TYPE_INT, (int) bitrate, NULL);

                if (gst_tag_list_get_uint (stream_tag_list,
                                           "maximum-bitrate",
                                           &bitrate))
                        gst_caps_set_simple (caps,
                                             "maximum-bitrate",
                                             G_TYPE_INT,
                                             (int) bitrate,
                                             NULL);
        }

        return caps;
}
static gchar *
gst_stream_audio_information_to_string (GstDiscovererStreamInfo * info,
    gint depth)
{
  GstDiscovererAudioInfo *audio_info;
  GString *s;
  gchar *tmp;
  const gchar *ctmp;
  int len = 400;
  const GstTagList *tags;
  GstCaps *caps;

  g_return_val_if_fail (info != NULL, NULL);

  s = g_string_sized_new (len);

  my_g_string_append_printf (s, depth, "Codec:\n");
  caps = gst_discoverer_stream_info_get_caps (info);
  tmp = gst_caps_to_string (caps);
  gst_caps_unref (caps);
  my_g_string_append_printf (s, depth, "  %s\n", tmp);
  g_free (tmp);

  my_g_string_append_printf (s, depth, "Additional info:\n");
  if (gst_discoverer_stream_info_get_misc (info)) {
    tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info));
    my_g_string_append_printf (s, depth, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, depth, "  None\n");
  }

  audio_info = (GstDiscovererAudioInfo *) info;
  ctmp = gst_discoverer_audio_info_get_language (audio_info);
  my_g_string_append_printf (s, depth, "Language: %s\n",
      ctmp ? ctmp : "<unknown>");
  my_g_string_append_printf (s, depth, "Channels: %u\n",
      gst_discoverer_audio_info_get_channels (audio_info));
  my_g_string_append_printf (s, depth, "Sample rate: %u\n",
      gst_discoverer_audio_info_get_sample_rate (audio_info));
  my_g_string_append_printf (s, depth, "Depth: %u\n",
      gst_discoverer_audio_info_get_depth (audio_info));

  my_g_string_append_printf (s, depth, "Bitrate: %u\n",
      gst_discoverer_audio_info_get_bitrate (audio_info));
  my_g_string_append_printf (s, depth, "Max bitrate: %u\n",
      gst_discoverer_audio_info_get_max_bitrate (audio_info));

  my_g_string_append_printf (s, depth, "Tags:\n");
  tags = gst_discoverer_stream_info_get_tags (info);
  if (tags) {
    tmp = gst_tag_list_to_string (tags);
    my_g_string_append_printf (s, depth, "  %s\n", tmp);
    g_free (tmp);
  } else {
    my_g_string_append_printf (s, depth, "  None\n");
  }
  if (verbose)
    my_g_string_append_printf (s, depth, "\n");

  return g_string_free (s, FALSE);
}
static gboolean
add_stream_to_profile (GstEncodingContainerProfile * profile,
    GstDiscovererStreamInfo * sinfo)
{
  GstEncodingProfile *sprofile = NULL;
  GstStructure *s;
  GstCaps *caps;

  caps = gst_discoverer_stream_info_get_caps (sinfo);

  /* Should unify this with copy_and_clean_caps() */
  s = gst_caps_get_structure (caps, 0);
  if (gst_structure_has_field (s, "codec_data")
      || gst_structure_has_field (s, "streamheader")
      || gst_structure_has_field (s, "parsed")
      || gst_structure_has_field (s, "framed")
      || gst_structure_has_field (s, "stream-format")
      || gst_structure_has_field (s, "alignment")) {
    caps = gst_caps_make_writable (caps);
    s = gst_caps_get_structure (caps, 0);
    gst_structure_remove_field (s, "codec_data");
    gst_structure_remove_field (s, "streamheader");
    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");
  }

  GST_LOG ("Stream: %" GST_PTR_FORMAT "\n", caps);
  if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
    sprofile =
        (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
        NULL, 0);
  } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
    sprofile =
        (GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
        NULL, 0);
  } else if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
    GList *streams, *stream;
    guint n_streams = 0;

    streams =
        gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
        (sinfo));
    for (stream = streams; stream; stream = stream->next) {
      if (add_stream_to_profile (profile,
              (GstDiscovererStreamInfo *) stream->data))
        n_streams++;
    }
    gst_discoverer_stream_info_list_free (streams);
    gst_caps_unref (caps);

    return n_streams != 0;
  } else {
    GST_WARNING ("Ignoring stream of type '%s'",
        g_type_name (G_OBJECT_TYPE (sinfo)));
    /* subtitles or other ? ignore for now */
  }
  if (sprofile)
    gst_encoding_container_profile_add_profile (profile, sprofile);
  else
    GST_ERROR ("Failed to create stream profile from caps %" GST_PTR_FORMAT,
        caps);
  gst_caps_unref (caps);

  return sprofile != NULL;
}
static gboolean
compare_encoding_profile_with_discoverer_stream (GstValidateFileChecker * fc,
    GstEncodingProfile * prof, GstDiscovererStreamInfo * stream, gchar ** msg)
{
  gboolean ret = TRUE;
  GstCaps *caps = NULL;
  const GstCaps *profile_caps;
  const GstCaps *restriction_caps;

  caps = gst_discoverer_stream_info_get_caps (stream);
  profile_caps = gst_encoding_profile_get_format (prof);
  restriction_caps = gst_encoding_profile_get_restriction (prof);

  /* TODO need to consider profile caps restrictions */
  if (!_gst_caps_can_intersect_safe (caps, profile_caps)) {
    gchar *caps_str = gst_caps_to_string (caps);
    gchar *profile_caps_str = gst_caps_to_string (profile_caps);
    SET_MESSAGE (msg, g_strdup_printf ("Caps '%s' didn't match profile '%s'",
            profile_caps_str, caps_str));
    g_free (caps_str);
    g_free (profile_caps_str);
    ret = FALSE;
    goto end;
  }

  if (restriction_caps) {
    GstStructure *structure;
    gint i;
    gboolean found = FALSE;

    for (i = 0; i < gst_caps_get_size (restriction_caps); i++) {
      structure = gst_caps_get_structure (restriction_caps, i);
      structure = gst_structure_copy (structure);
      gst_structure_set_name (structure,
          gst_structure_get_name (gst_caps_get_structure (caps, 0)));
      if (gst_structure_can_intersect (structure, gst_caps_get_structure (caps,
                  0))) {
        gst_structure_free (structure);
        found = TRUE;
        break;
      }
      gst_structure_free (structure);
    }
    if (!found) {
      gchar *caps_str = gst_caps_to_string (caps);
      gchar *restriction_caps_str = gst_caps_to_string (restriction_caps);
      SET_MESSAGE (msg,
          g_strdup_printf ("Caps restriction '%s' wasn't respected on file "
              "with caps '%s'", restriction_caps_str, caps_str));
      g_free (caps_str);
      g_free (restriction_caps_str);
      ret = FALSE;
      goto end;
    }
  }

  if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) {
    if (GST_IS_DISCOVERER_CONTAINER_INFO (stream)) {
      ret =
          ret & compare_container_profile_with_container_discoverer_stream (fc,
          (GstEncodingContainerProfile *) prof,
          (GstDiscovererContainerInfo *) stream, msg);
    } else {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected container profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }

  } else if (GST_IS_ENCODING_VIDEO_PROFILE (prof)) {
    if (!GST_IS_DISCOVERER_VIDEO_INFO (stream)) {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected video profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }

  } else if (GST_IS_ENCODING_AUDIO_PROFILE (prof)) {
    if (!GST_IS_DISCOVERER_AUDIO_INFO (stream)) {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected audio profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }
  } else {
    g_assert_not_reached ();
    return FALSE;
  }


end:
  if (caps)
    gst_caps_unref (caps);

  return ret;
}
static gboolean
    compare_container_profile_with_container_discoverer_stream
    (GstValidateFileChecker * fc, GstEncodingContainerProfile * prof,
    GstDiscovererContainerInfo * stream, gchar ** msg)
{
  ExpectedStream *expected_streams = NULL;
  GList *container_streams;
  const GList *profile_iter;
  const GList *streams_iter;
  gint i;
  gint expected_count = g_list_length ((GList *)
      gst_encoding_container_profile_get_profiles (prof));
  gboolean ret = TRUE;

  container_streams = gst_discoverer_container_info_get_streams (stream);

  if (expected_count == 0) {
    if (g_list_length (container_streams) != 0) {
      SET_MESSAGE (msg,
          g_strdup_printf
          ("No streams expected on this container, but found %u",
              g_list_length (container_streams)));
      ret = FALSE;
      goto end;
    }
  }

  /* initialize expected streams data */
  expected_streams = g_malloc0 (sizeof (ExpectedStream) * expected_count);
  for (i = 0, profile_iter = gst_encoding_container_profile_get_profiles (prof);
      profile_iter; profile_iter = g_list_next (profile_iter), i++) {
    GstEncodingProfile *prof = profile_iter->data;
    ExpectedStream *expected = &(expected_streams[i]);

    expected->profile = prof;
  }

  /* look for the streams on discoverer info */
  for (streams_iter = container_streams; streams_iter;
      streams_iter = g_list_next (streams_iter)) {
    GstDiscovererStreamInfo *info = streams_iter->data;
    gboolean found = FALSE;
    for (i = 0; i < expected_count; i++) {
      ExpectedStream *expected = &(expected_streams[i]);

      if (compare_encoding_profile_with_discoverer_stream (fc,
              expected->profile, info, NULL)) {
        found = TRUE;
        break;
      }
    }

    if (!found) {
      GstCaps *caps = gst_discoverer_stream_info_get_caps (info);
      gchar *caps_str = gst_caps_to_string (caps);
      SET_MESSAGE (msg,
          g_strdup_printf ("Stream with caps '%s' wasn't found on file",
              caps_str));
      g_free (caps_str);
      gst_caps_unref (caps);
      ret = FALSE;
      goto end;
    }
  }

  /* check if all expected streams are present */
  for (i = 0; i < expected_count; i++) {
    ExpectedStream *expected = &(expected_streams[i]);
    guint presence = gst_encoding_profile_get_presence (expected->profile);

    if (presence == 0)
      continue;

    if (presence != expected->count) {
      gchar *caps_str =
          gst_caps_to_string (gst_encoding_profile_get_format
          (expected->profile));
      SET_MESSAGE (msg,
          g_strdup_printf ("Stream from profile %s (with caps '%s"
              "' has presence %u but the number of streams found was %d",
              gst_encoding_profile_get_name (expected->profile), caps_str,
              presence, expected->count));
      g_free (caps_str);
      ret = FALSE;
      goto end;
    }
  }

end:
  g_free (expected_streams);
  gst_discoverer_stream_info_list_free (container_streams);
  return ret;
}