return res;
}
+/* Serializing code */
+
+static GVariant *
+_serialize_common_stream_info (GstDiscovererStreamInfo * sinfo,
+ GstDiscovererSerializeFlags flags)
+{
+ GVariant *common;
+ gchar *caps_str = NULL, *tags_str = NULL, *misc_str = NULL;
+
+ if (sinfo->caps && (flags & GST_DISCOVERER_SERIALIZE_CAPS))
+ caps_str = gst_caps_to_string (sinfo->caps);
+
+ if (sinfo->tags && (flags & GST_DISCOVERER_SERIALIZE_TAGS))
+ tags_str = gst_tag_list_to_string (sinfo->tags);
+
+ if (sinfo->misc && (flags & GST_DISCOVERER_SERIALIZE_MISC))
+ misc_str = gst_structure_to_string (sinfo->misc);
+
+ common =
+ g_variant_new ("(msmsmsms)", sinfo->stream_id, caps_str, tags_str,
+ misc_str);
+
+ g_free (caps_str);
+ g_free (tags_str);
+ g_free (misc_str);
+
+ return common;
+}
+
+static GVariant *
+_serialize_audio_stream_info (GstDiscovererAudioInfo * ainfo)
+{
+ return g_variant_new ("(uuuuums)",
+ ainfo->channels,
+ ainfo->sample_rate,
+ ainfo->bitrate, ainfo->max_bitrate, ainfo->depth, ainfo->language);
+}
+
+static GVariant *
+_serialize_video_stream_info (GstDiscovererVideoInfo * vinfo)
+{
+ return g_variant_new ("(uuuuuuubuub)",
+ vinfo->width,
+ vinfo->height,
+ vinfo->depth,
+ vinfo->framerate_num,
+ vinfo->framerate_denom,
+ vinfo->par_num,
+ vinfo->par_denom,
+ vinfo->interlaced, vinfo->bitrate, vinfo->max_bitrate, vinfo->is_image);
+}
+
+static GVariant *
+_serialize_subtitle_stream_info (GstDiscovererSubtitleInfo * sinfo)
+{
+ return g_variant_new ("ms", sinfo->language);
+}
+
+static GVariant *
+gst_discoverer_info_to_variant_recurse (GstDiscovererStreamInfo * sinfo,
+ GstDiscovererSerializeFlags flags)
+{
+ GVariant *stream_variant = NULL;
+ GVariant *common_stream_variant =
+ _serialize_common_stream_info (sinfo, flags);
+
+ if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
+ GList *tmp;
+ GList *streams =
+ gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
+ (sinfo));
+
+ if (g_list_length (streams) > 0) {
+ GVariantBuilder children;
+ GVariant *child_variant;
+ g_variant_builder_init (&children, G_VARIANT_TYPE_ARRAY);
+
+ for (tmp = streams; tmp; tmp = tmp->next) {
+ child_variant =
+ gst_discoverer_info_to_variant_recurse (tmp->data, flags);
+ g_variant_builder_add (&children, "v", child_variant);
+ }
+ stream_variant =
+ g_variant_new ("(yvav)", 'c', common_stream_variant, &children);
+ } else {
+ stream_variant =
+ g_variant_new ("(yvav)", 'c', common_stream_variant, NULL);
+ }
+
+ gst_discoverer_stream_info_list_free (streams);
+ } else if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
+ GVariant *audio_stream_info =
+ _serialize_audio_stream_info (GST_DISCOVERER_AUDIO_INFO (sinfo));
+ stream_variant =
+ g_variant_new ("(yvv)", 'a', common_stream_variant, audio_stream_info);
+ } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
+ GVariant *video_stream_info =
+ _serialize_video_stream_info (GST_DISCOVERER_VIDEO_INFO (sinfo));
+ stream_variant =
+ g_variant_new ("(yvv)", 'v', common_stream_variant, video_stream_info);
+ } else if (GST_IS_DISCOVERER_SUBTITLE_INFO (sinfo)) {
+ GVariant *subtitle_stream_info =
+ _serialize_subtitle_stream_info (GST_DISCOVERER_SUBTITLE_INFO (sinfo));
+ stream_variant =
+ g_variant_new ("(yvv)", 's', common_stream_variant,
+ subtitle_stream_info);
+ }
+
+ return stream_variant;
+}
+
+/* Parsing code */
+
+#define GET_FROM_TUPLE(v, t, n, val) G_STMT_START{ \
+ GVariant *child = g_variant_get_child_value (v, n); \
+ *val = g_variant_get_##t(child); \
+ g_variant_unref (child); \
+}G_STMT_END
+
+static const gchar *
+_maybe_get_string_from_tuple (GVariant * tuple, guint index)
+{
+ const gchar *ret = NULL;
+ GVariant *maybe;
+ GET_FROM_TUPLE (tuple, maybe, index, &maybe);
+ if (maybe) {
+ ret = g_variant_get_string (maybe, NULL);
+ g_variant_unref (maybe);
+ }
+
+ return ret;
+}
+
+static void
+_parse_common_stream_info (GstDiscovererStreamInfo * sinfo, GVariant * common)
+{
+ const gchar *str;
+
+ str = _maybe_get_string_from_tuple (common, 0);
+ if (str)
+ sinfo->stream_id = g_strdup (str);
+
+ str = _maybe_get_string_from_tuple (common, 1);
+ if (str)
+ sinfo->caps = gst_caps_from_string (str);
+
+ str = _maybe_get_string_from_tuple (common, 2);
+ if (str)
+ sinfo->tags = gst_tag_list_new_from_string (str);
+
+ str = _maybe_get_string_from_tuple (common, 3);
+ if (str)
+ sinfo->misc = gst_structure_new_from_string (str);
+
+ g_variant_unref (common);
+}
+
+static void
+_parse_audio_stream_info (GstDiscovererAudioInfo * ainfo, GVariant * specific)
+{
+ const gchar *str;
+
+ GET_FROM_TUPLE (specific, uint32, 0, &ainfo->channels);
+ GET_FROM_TUPLE (specific, uint32, 1, &ainfo->sample_rate);
+ GET_FROM_TUPLE (specific, uint32, 2, &ainfo->bitrate);
+ GET_FROM_TUPLE (specific, uint32, 3, &ainfo->max_bitrate);
+ GET_FROM_TUPLE (specific, uint32, 4, &ainfo->depth);
+
+ str = _maybe_get_string_from_tuple (specific, 5);
+
+ if (str)
+ ainfo->language = g_strdup (str);
+
+ g_variant_unref (specific);
+}
+
+static void
+_parse_video_stream_info (GstDiscovererVideoInfo * vinfo, GVariant * specific)
+{
+ GET_FROM_TUPLE (specific, uint32, 0, &vinfo->width);
+ GET_FROM_TUPLE (specific, uint32, 1, &vinfo->height);
+ GET_FROM_TUPLE (specific, uint32, 2, &vinfo->depth);
+ GET_FROM_TUPLE (specific, uint32, 3, &vinfo->framerate_num);
+ GET_FROM_TUPLE (specific, uint32, 4, &vinfo->framerate_denom);
+ GET_FROM_TUPLE (specific, uint32, 5, &vinfo->par_num);
+ GET_FROM_TUPLE (specific, uint32, 6, &vinfo->par_denom);
+ GET_FROM_TUPLE (specific, boolean, 7, &vinfo->interlaced);
+ GET_FROM_TUPLE (specific, uint32, 8, &vinfo->bitrate);
+ GET_FROM_TUPLE (specific, uint32, 9, &vinfo->max_bitrate);
+ GET_FROM_TUPLE (specific, boolean, 10, &vinfo->is_image);
+
+ g_variant_unref (specific);
+}
+
+static void
+_parse_subtitle_stream_info (GstDiscovererSubtitleInfo * sinfo,
+ GVariant * specific)
+{
+ GVariant *maybe;
+
+ maybe = g_variant_get_maybe (specific);
+ if (maybe) {
+ sinfo->language = g_strdup (g_variant_get_string (maybe, NULL));
+ g_variant_unref (maybe);
+ }
+
+ g_variant_unref (specific);
+}
+
+static GstDiscovererStreamInfo *
+_parse_discovery (GVariant * variant, GstDiscovererInfo * info)
+{
+ gchar type;
+ GVariant *common = g_variant_get_child_value (variant, 1);
+ GVariant *specific = g_variant_get_child_value (variant, 2);
+ GstDiscovererStreamInfo *sinfo = NULL;
+
+ GET_FROM_TUPLE (variant, byte, 0, &type);
+ switch (type) {
+ case 'c':
+ sinfo = g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
+ break;
+ case 'a':
+ sinfo = g_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO, NULL);
+ _parse_audio_stream_info (GST_DISCOVERER_AUDIO_INFO (sinfo),
+ g_variant_get_child_value (specific, 0));
+ break;
+ case 'v':
+ sinfo = g_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO, NULL);
+ _parse_video_stream_info (GST_DISCOVERER_VIDEO_INFO (sinfo),
+ g_variant_get_child_value (specific, 0));
+ break;
+ case 's':
+ sinfo = g_object_new (GST_TYPE_DISCOVERER_SUBTITLE_INFO, NULL);
+ _parse_subtitle_stream_info (GST_DISCOVERER_SUBTITLE_INFO (sinfo),
+ g_variant_get_child_value (specific, 0));
+ break;
+ default:
+ break;
+ }
+
+ _parse_common_stream_info (sinfo, g_variant_get_child_value (common, 0));
+
+ info->stream_list = g_list_append (info->stream_list, sinfo);
+
+ if (!info->stream_info) {
+ info->stream_info = sinfo;
+ }
+
+ if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
+ GVariantIter iter;
+ GVariant *child;
+
+ GstDiscovererContainerInfo *cinfo = GST_DISCOVERER_CONTAINER_INFO (sinfo);
+ g_variant_iter_init (&iter, specific);
+ while ((child = g_variant_iter_next_value (&iter))) {
+ GstDiscovererStreamInfo *child_info;
+ child_info = _parse_discovery (g_variant_get_variant (child), info);
+ cinfo->streams =
+ g_list_append (cinfo->streams,
+ gst_discoverer_stream_info_ref (child_info));
+ g_variant_unref (child);
+ }
+ }
+
+ g_variant_unref (common);
+ g_variant_unref (specific);
+ g_variant_unref (variant);
+ return sinfo;
+}
/**
* gst_discoverer_start:
}
return res;
}
+
+/**
+ * gst_discoverer_info_to_variant:
+ * @info: A #GstDiscovererInfo
+ * @flags: A combination of #GstDiscovererSerializeFlags to specify
+ * what needs to be serialized.
+ *
+ * Serializes @info to a #GVariant that can be parsed again
+ * through gst_discoverer_info_from_variant().
+ *
+ * Note that any #GstToc (s) that might have been discovered will not be serialized
+ * for now.
+ *
+ * Returns: (transfer full): A newly-allocated #GVariant representing @info.
+ *
+ * Since: 1.6
+ */
+GVariant *
+gst_discoverer_info_to_variant (GstDiscovererInfo * info,
+ GstDiscovererSerializeFlags flags)
+{
+ /* FIXME: implement TOC support */
+ GVariant *variant;
+ GstDiscovererStreamInfo *sinfo = gst_discoverer_info_get_stream_info (info);
+ GVariant *wrapper;
+
+ variant = gst_discoverer_info_to_variant_recurse (sinfo, flags);
+ /* Returning a wrapper implies some small overhead, but simplifies
+ * deserializing from bytes */
+ wrapper = g_variant_new_variant (variant);
+
+ gst_discoverer_stream_info_unref (sinfo);
+ return wrapper;
+}
+
+/**
+ * gst_discoverer_info_from_variant:
+ * @variant: A #GVariant to deserialize into a #GstDiscovererInfo.
+ *
+ * Parses a #GVariant as produced by gst_discoverer_info_to_variant()
+ * back to a #GstDiscovererInfo.
+ *
+ * Returns: (transfer full): A newly-allocated #GstDiscovererInfo.
+ *
+ * Since: 1.6
+ */
+GstDiscovererInfo *
+gst_discoverer_info_from_variant (GVariant * variant)
+{
+ GstDiscovererInfo *info = g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
+ GVariant *wrapped = g_variant_get_variant (variant);
+
+ _parse_discovery (wrapped, info);
+
+ return info;
+}