mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-29 18:48:44 +00:00
sample: add serialisation/deserialisation functions for GstSample
Since these things are inside taglists now, it would be good to be able to print them and deserialise them. https://bugzilla.gnome.org/show_bug.cgi?id=681322
This commit is contained in:
parent
3834968dd2
commit
c2175db889
3 changed files with 204 additions and 5 deletions
|
@ -1682,6 +1682,8 @@ gst_structure_get_abbrs (gint * n_abbrs)
|
|||
,
|
||||
{"bitmask", GST_TYPE_BITMASK}
|
||||
,
|
||||
{"sample", GST_TYPE_SAMPLE}
|
||||
,
|
||||
{"taglist", GST_TYPE_TAG_LIST}
|
||||
};
|
||||
_num = G_N_ELEMENTS (dyn_abbrs);
|
||||
|
|
164
gst/gstvalue.c
164
gst/gstvalue.c
|
@ -1837,8 +1837,9 @@ gst_value_deserialize_caps (GValue * dest, const gchar * s)
|
|||
/**************
|
||||
* 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;
|
||||
|
@ -1857,13 +1858,23 @@ gst_value_serialize_segment (const GValue * value)
|
|||
"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)
|
||||
{
|
||||
|
@ -2151,6 +2162,149 @@ gst_value_compare_sample (const GValue * value1, const GValue * value2)
|
|||
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 *
|
||||
***********/
|
||||
|
@ -5801,8 +5955,8 @@ _priv_gst_value_initialize (void)
|
|||
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;
|
||||
|
|
|
@ -566,6 +566,48 @@ GST_START_TEST (test_writability)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -585,6 +627,7 @@ 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue