/**************
* GstSegment *
**************/
+
static gchar *
-gst_value_serialize_segment (const GValue * value)
+gst_value_serialize_segment_internal (const GValue * value, gboolean escape)
{
GstSegment *seg = g_value_get_boxed (value);
gchar *t, *res;
"position", G_TYPE_UINT64, seg->position,
"duration", G_TYPE_UINT64, seg->duration, NULL);
t = gst_structure_to_string (s);
- res = g_strdup_printf ("\"%s\"", t);
- g_free (t);
+ if (escape) {
+ res = g_strdup_printf ("\"%s\"", t);
+ g_free (t);
+ } else {
+ res = t;
+ }
gst_structure_free (s);
return res;
}
+static gchar *
+gst_value_serialize_segment (const GValue * value)
+{
+ return gst_value_serialize_segment_internal (value, TRUE);
+}
+
static gboolean
gst_value_deserialize_segment (GValue * dest, const gchar * s)
{
return compare_buffer (buf1, buf2);
}
+static gchar *
+gst_value_serialize_sample (const GValue * value)
+{
+ const GstStructure *info_structure;
+ GstSegment *segment;
+ GstBuffer *buffer;
+ GstCaps *caps;
+ GstSample *sample;
+ GValue val = { 0, };
+ gchar *info_str, *caps_str, *tmp;
+ gchar *buf_str, *seg_str, *s;
+
+ sample = g_value_get_boxed (value);
+
+ buffer = gst_sample_get_buffer (sample);
+ if (buffer) {
+ g_value_init (&val, GST_TYPE_BUFFER);
+ g_value_set_boxed (&val, buffer);
+ buf_str = gst_value_serialize_buffer (&val);
+ g_value_unset (&val);
+ } else {
+ buf_str = g_strdup ("None");
+ }
+
+ caps = gst_sample_get_caps (sample);
+ if (caps) {
+ tmp = gst_caps_to_string (caps);
+ caps_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
+ g_strdelimit (caps_str, "=", '_');
+ g_free (tmp);
+ } else {
+ caps_str = g_strdup ("None");
+ }
+
+ segment = gst_sample_get_segment (sample);
+ if (segment) {
+ g_value_init (&val, GST_TYPE_SEGMENT);
+ g_value_set_boxed (&val, segment);
+ tmp = gst_value_serialize_segment_internal (&val, FALSE);
+ seg_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
+ g_strdelimit (seg_str, "=", '_');
+ g_free (tmp);
+ g_value_unset (&val);
+ } else {
+ seg_str = g_strdup ("None");
+ }
+
+ info_structure = gst_sample_get_info (sample);
+ if (info_structure) {
+ tmp = gst_structure_to_string (info_structure);
+ info_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
+ g_strdelimit (info_str, "=", '_');
+ g_free (tmp);
+ } else {
+ info_str = g_strdup ("None");
+ }
+
+ s = g_strconcat (buf_str, ":", caps_str, ":", seg_str, ":", info_str, NULL);
+ g_free (buf_str);
+ g_free (caps_str);
+ g_free (seg_str);
+ g_free (info_str);
+
+ return s;
+}
+
+static gboolean
+gst_value_deserialize_sample (GValue * dest, const gchar * s)
+{
+ GValue bval = G_VALUE_INIT, sval = G_VALUE_INIT;
+ GstStructure *info;
+ GstSample *sample;
+ GstCaps *caps;
+ gboolean ret = FALSE;
+ gchar **fields;
+ gsize outlen;
+ gint len;
+
+ GST_TRACE ("deserialize '%s'", s);
+
+ fields = g_strsplit (s, ":", -1);
+ len = g_strv_length (fields);
+ if (len != 4)
+ goto wrong_length;
+
+ g_value_init (&bval, GST_TYPE_BUFFER);
+ g_value_init (&sval, GST_TYPE_SEGMENT);
+
+ if (!gst_value_deserialize_buffer (&bval, fields[0]))
+ goto fail;
+
+ if (strcmp (fields[1], "None") != 0) {
+ g_strdelimit (fields[1], "_", '=');
+ g_base64_decode_inplace (fields[1], &outlen);
+ GST_TRACE ("caps : %s", fields[1]);
+ caps = gst_caps_from_string (fields[1]);
+ if (caps == NULL)
+ goto fail;
+ } else {
+ caps = NULL;
+ }
+
+ if (strcmp (fields[2], "None") != 0) {
+ g_strdelimit (fields[2], "_", '=');
+ g_base64_decode_inplace (fields[2], &outlen);
+ GST_TRACE ("segment : %s", fields[2]);
+ if (!gst_value_deserialize_segment (&sval, fields[2]))
+ goto fail;
+ }
+
+ if (strcmp (fields[3], "None") != 0) {
+ g_strdelimit (fields[3], "_", '=');
+ g_base64_decode_inplace (fields[3], &outlen);
+ GST_TRACE ("info : %s", fields[3]);
+ info = gst_structure_from_string (fields[3], NULL);
+ if (info == NULL)
+ goto fail;
+ } else {
+ info = NULL;
+ }
+
+ sample = gst_sample_new (gst_value_get_buffer (&bval), caps,
+ g_value_get_boxed (&sval), info);
+
+ g_value_take_boxed (dest, sample);
+
+ if (caps)
+ gst_caps_unref (caps);
+
+ ret = TRUE;
+
+fail:
+
+ g_value_unset (&bval);
+ g_value_unset (&sval);
+
+wrong_length:
+
+ g_strfreev (fields);
+
+ return ret;
+}
+
/***********
* boolean *
***********/
static GstValueTable gst_value = {
0,
gst_value_compare_sample,
- NULL,
- NULL,
+ gst_value_serialize_sample,
+ gst_value_deserialize_sample,
};
gst_value.type = GST_TYPE_SAMPLE;
GST_END_TEST;
+/* this tests GstSample serialisation/deserialisation, esp. with multiple
+ * samples in a tag list */
+GST_START_TEST (test_serialization)
+{
+ GstTagList *tags, *tags2;
+ GstBuffer *b1, *b2;
+ GstSample *s1, *s2;
+ GstCaps *c2;
+ gchar *s;
+
+ b1 = gst_buffer_new_allocate (NULL, 1, NULL);
+ gst_buffer_memset (b1, 0, 0xb3, -1);
+ s1 = gst_sample_new (b1, NULL, NULL, NULL);
+ gst_buffer_unref (b1);
+
+ b2 = gst_buffer_new_allocate (NULL, 8, NULL);
+ gst_buffer_memset (b2, 0, 0x2f, -1);
+ c2 = gst_caps_new_empty_simple ("foo/bar");
+ s2 = gst_sample_new (b2, c2, NULL, NULL);
+ gst_buffer_unref (b2);
+ gst_caps_unref (c2);
+ c2 = NULL;
+
+ tags = gst_tag_list_new (GST_TAG_ATTACHMENT, s1, NULL);
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT, s2, NULL);
+ GST_INFO ("tags: %" GST_PTR_FORMAT, tags);
+
+ s = gst_tag_list_to_string (tags);
+ GST_INFO ("taglist -> string: %s", s);
+ tags2 = gst_tag_list_new_from_string (s);
+ GST_INFO ("string -> taglist: %" GST_PTR_FORMAT, tags2);
+ fail_unless (gst_tag_list_is_equal (tags, tags2));
+ gst_tag_list_unref (tags2);
+ g_free (s);
+
+ gst_sample_unref (s1);
+ gst_sample_unref (s2);
+ gst_tag_list_unref (tags);
+}
+
+GST_END_TEST;
+
static Suite *
gst_tag_suite (void)
{
tcase_add_test (tc_chain, test_new_full);
tcase_add_test (tc_chain, test_equal);
tcase_add_test (tc_chain, test_writability);
+ tcase_add_test (tc_chain, test_serialization);
return s;
}