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; }
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; }
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; }