GUPnPDLNAInformation * gupnp_dlna_information_new_from_discoverer_info (GstDiscovererInfo *info, GList *profiles) { GUPnPDLNAInformation *dlna; GList *video_list, *audio_list; gchar *name = NULL, *mime = NULL; video_list = gst_discoverer_info_get_video_streams (info); audio_list = gst_discoverer_info_get_audio_streams (info); if (video_list) { if ((g_list_length (video_list) ==1 ) && gst_discoverer_video_info_is_image (GST_DISCOVERER_VIDEO_INFO (video_list->data))) { GstDiscovererStreamInfo *stream; stream = (GstDiscovererStreamInfo *) video_list->data; guess_image_profile (stream, &name, &mime, profiles); } else guess_video_profile (info, &name, &mime, profiles); } else if (audio_list) guess_audio_profile (info, &name, &mime, profiles); gst_discoverer_stream_info_list_free (audio_list); gst_discoverer_stream_info_list_free (video_list); dlna = gupnp_dlna_information_new (name, mime, info); g_free (name); g_free (mime); return dlna; }
GUPnPDLNAGstImageInformation * gupnp_dlna_gst_image_information_new_from_discoverer_info (GstDiscovererInfo *info) { GList* image_list; GUPnPDLNAGstImageInformation *image_info = NULL; g_return_val_if_fail (GST_IS_DISCOVERER_INFO (info), NULL); image_list = gst_discoverer_info_get_video_streams (info); if (image_list) { if ((image_list->next == NULL) && gst_discoverer_video_info_is_image (GST_DISCOVERER_VIDEO_INFO (image_list->data))) image_info = GUPNP_DLNA_GST_IMAGE_INFORMATION (g_object_new (GUPNP_TYPE_DLNA_GST_IMAGE_INFORMATION, "info", info, NULL)); gst_discoverer_stream_info_list_free (image_list); } return image_info; }
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); } }
static gboolean check_video_profile (GstDiscovererInfo *info, GstEncodingProfile *profile) { GList *i, *stream_list; gboolean found_video = FALSE, found_audio = FALSE;; stream_list = gst_discoverer_info_get_stream_list (info); /* Check video and audio restrictions */ for (i = stream_list; i && !(found_video && found_audio); i = i->next) { GstDiscovererStreamInfo *stream; GType stream_type; GstCaps *caps = NULL; stream = GST_DISCOVERER_STREAM_INFO(i->data); stream_type = G_TYPE_FROM_INSTANCE (stream); if (!found_video && stream_type == GST_TYPE_DISCOVERER_VIDEO_INFO) { caps = caps_from_video_stream_info (stream); if (match_profile (profile, caps, GST_TYPE_ENCODING_VIDEO_PROFILE)) found_video = TRUE; else gupnp_dlna_debug (" Video did not match"); } else if (!found_audio && stream_type == GST_TYPE_DISCOVERER_AUDIO_INFO) { caps = caps_from_audio_stream_info (stream); if (match_profile (profile, caps, GST_TYPE_ENCODING_AUDIO_PROFILE)) found_audio = TRUE; else gupnp_dlna_debug (" Audio did not match"); } if (caps) gst_caps_unref (caps); } gst_discoverer_stream_info_list_free (stream_list); if (!found_video || !found_audio) return FALSE; /* Check container restrictions */ if (!check_container (info, profile)) { gupnp_dlna_debug (" Container did not match"); return FALSE; } return TRUE; }
static gboolean check_is_image (GstDiscovererInfo * info) { gboolean ret = FALSE; GList *video_streams = gst_discoverer_info_get_video_streams (info); if (g_list_length (video_streams) == 1) { if (gst_discoverer_video_info_is_image (video_streams->data)) { GList *audio_streams = gst_discoverer_info_get_audio_streams (info); if (audio_streams == NULL) ret = TRUE; else gst_discoverer_stream_info_list_free (audio_streams); } } gst_discoverer_stream_info_list_free (video_streams); return ret; }
static void gst_discoverer_container_info_finalize (GstDiscovererContainerInfo * info) { GList *tmp; for (tmp = ((GstDiscovererContainerInfo *) info)->streams; tmp; tmp = tmp->next) gst_mini_object_unref ((GstMiniObject *) tmp->data); gst_discoverer_stream_info_list_free (info->streams); gst_discoverer_stream_info_finalize ((GstDiscovererStreamInfo *) info); }
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_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; }
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 check_audio_profile (GstDiscovererInfo *info, GstEncodingProfile *profile) { GstCaps *caps; GList *i, *stream_list; gboolean found = FALSE; /* Optimisation TODO: this can be pre-computed */ if (is_video_profile (profile)) return FALSE; stream_list = gst_discoverer_info_get_stream_list (info); for (i = stream_list; !found && i; i = i->next) { GstDiscovererStreamInfo *stream = GST_DISCOVERER_STREAM_INFO(i->data); GType stream_type = G_TYPE_FROM_INSTANCE (stream); if (stream_type != GST_TYPE_DISCOVERER_AUDIO_INFO) continue; caps = caps_from_audio_stream_info (stream); if (match_profile (profile, caps, GST_TYPE_ENCODING_AUDIO_PROFILE)) { found = TRUE; break; } gst_caps_unref (caps); } gst_discoverer_stream_info_list_free (stream_list); return found; }
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; }
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; }
void Discoverer::on_discovered(GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, Gstreamer *gst) { Q_UNUSED(err); Q_UNUSED(discoverer); Metadata *meta = gst->getMetadata(); delete meta; GstDiscovererResult result; result = gst_discoverer_info_get_result(info); if (result != GST_DISCOVERER_OK) { gst->setMetadata(nullptr); return; } meta = new Metadata(); // is seekable meta->setSeekable(gst_discoverer_info_get_seekable(info)); // extract duration qint64 time = gst_discoverer_info_get_duration(info); meta->setDuration(UTime(time)); // extract filename QUrl uri(gst_discoverer_info_get_uri(info)); meta->setFilename(uri.toLocalFile()); // set filesize QFile file(uri.toLocalFile()); meta->setSize(file.size()); // extract tags const GstTagList *tags; tags = gst_discoverer_info_get_tags(info); if (tags) { gst_tag_list_foreach(tags, fillTags, meta); } GList *list, *iterator; // extract video streams iterator = list = gst_discoverer_info_get_video_streams(info); while (iterator) { Video video; GstDiscovererVideoInfo *vInfo = (GstDiscovererVideoInfo *)iterator->data; video.Width = gst_discoverer_video_info_get_width(vInfo); video.Height = gst_discoverer_video_info_get_height(vInfo); video.Framerate = double(gst_discoverer_video_info_get_framerate_num(vInfo)) / double(gst_discoverer_video_info_get_framerate_denom(vInfo)); meta->addVideo(video); iterator = iterator->next; } gst_discoverer_stream_info_list_free(list); // extract audio streams iterator = list = gst_discoverer_info_get_audio_streams(info); while (iterator) { Audio audio; GstDiscovererAudioInfo *aInfo = (GstDiscovererAudioInfo *)iterator->data; audio.Channels = gst_discoverer_audio_info_get_channels(aInfo); audio.SampleRate = gst_discoverer_audio_info_get_sample_rate(aInfo); audio.Language = gst_discoverer_audio_info_get_language(aInfo); meta->addAudio(audio); iterator = iterator->next; } gst_discoverer_stream_info_list_free(list); // extract subtitle streams iterator = list = gst_discoverer_info_get_subtitle_streams(info); while (iterator) { Subtitle subtitle; GstDiscovererSubtitleInfo *sInfo = (GstDiscovererSubtitleInfo *)iterator->data; gst_discoverer_subtitle_info_get_language(sInfo); subtitle.Language = gst_discoverer_subtitle_info_get_language(sInfo); meta->addSubtitles(subtitle); iterator = iterator->next; } gst_discoverer_stream_info_list_free(list); // fill metadata gst->setMetadata(meta); QObject::connect(gst->getMetadata(), SIGNAL(updated()), gst, SLOT(on_metadata_update())); }