예제 #1
0
static void
print_topology (GstDiscovererStreamInfo * info, gint depth)
{
  GstDiscovererStreamInfo *next;

  if (!info)
    return;

  print_stream_info (info, GINT_TO_POINTER (depth));

  next = gst_discoverer_stream_info_get_next (info);
  if (next) {
    print_topology (next, depth + 1);
    gst_discoverer_stream_info_unref (next);
  } else if (GST_IS_DISCOVERER_CONTAINER_INFO (info)) {
    GList *tmp, *streams;

    streams =
        gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
        (info));
    for (tmp = streams; tmp; tmp = tmp->next) {
      GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data;
      print_topology (tmpinf, depth + 1);
    }
    gst_discoverer_stream_info_list_free (streams);
  }
}
GList *
gst_discoverer_container_info_get_streams (GstDiscovererContainerInfo * info)
{
  GList *res = NULL, *tmp;

  g_return_val_if_fail (GST_IS_DISCOVERER_CONTAINER_INFO (info), NULL);

  for (tmp = info->streams; tmp; tmp = tmp->next)
    res =
        g_list_append (res,
        gst_discoverer_stream_info_ref ((GstDiscovererStreamInfo *) tmp->data));

  return res;
}
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);
}
/**
 * gst_discoverer_stream_info_get_stream_type_nick:
 * @info: a #GstDiscovererStreamInfo
 *
 * Returns: a human readable name for the stream type of the given @info (ex : "audio",
 * "container",...).
 *
 * Since: 0.10.31
 */
const gchar *
gst_discoverer_stream_info_get_stream_type_nick (GstDiscovererStreamInfo * info)
{
  if (GST_IS_DISCOVERER_CONTAINER_INFO (info))
    return "container";
  if (GST_IS_DISCOVERER_AUDIO_INFO (info))
    return "audio";
  if (GST_IS_DISCOVERER_VIDEO_INFO (info)) {
    if (gst_discoverer_video_info_is_image ((GstDiscovererVideoInfo *)
            info))
      return "video(image)";
    else
      return "video";
  }
  return "unknown";
}
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;
}
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;
}
예제 #7
0
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;
}
예제 #8
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;
}