/* GStreamer * * unit tests for the tag support library * * Copyright (C) 2006-2009 Tim-Philipp Müller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include GST_START_TEST (test_parse_extended_comment) { gchar *key, *val, *lang; /* first check the g_return_val_if_fail conditions */ ASSERT_CRITICAL (gst_tag_parse_extended_comment (NULL, NULL, NULL, NULL, FALSE)); ASSERT_CRITICAL (gst_tag_parse_extended_comment ("\377\000", NULL, NULL, NULL, FALSE)); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("a=b", &key, &lang, &val, FALSE) == TRUE); fail_unless (key != NULL); fail_unless (lang == NULL); fail_unless (val != NULL); fail_unless_equals_string (key, "a"); fail_unless_equals_string (val, "b"); g_free (key); g_free (lang); g_free (val); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("a[l]=b", &key, &lang, &val, FALSE) == TRUE); fail_unless (key != NULL); fail_unless (lang != NULL); fail_unless (val != NULL); fail_unless_equals_string (key, "a"); fail_unless_equals_string (lang, "l"); fail_unless_equals_string (val, "b"); g_free (key); g_free (lang); g_free (val); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("foo=bar", &key, &lang, &val, FALSE) == TRUE); fail_unless (key != NULL); fail_unless (lang == NULL); fail_unless (val != NULL); fail_unless_equals_string (key, "foo"); fail_unless_equals_string (val, "bar"); g_free (key); g_free (lang); g_free (val); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", &key, &lang, &val, FALSE) == TRUE); fail_unless (key != NULL); fail_unless (lang != NULL); fail_unless (val != NULL); fail_unless_equals_string (key, "foo"); fail_unless_equals_string (lang, "fr"); fail_unless_equals_string (val, "bar"); g_free (key); g_free (lang); g_free (val); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("foo=[fr]bar", &key, &lang, &val, FALSE) == TRUE); fail_unless (key != NULL); fail_unless (lang == NULL); fail_unless (val != NULL); fail_unless_equals_string (key, "foo"); fail_unless_equals_string (val, "[fr]bar"); g_free (key); g_free (lang); g_free (val); /* test NULL for output locations */ fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", NULL, NULL, NULL, FALSE) == TRUE); /* test strict mode (key must be specified) */ fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", NULL, NULL, NULL, TRUE) == TRUE); fail_unless (gst_tag_parse_extended_comment ("foo=bar", NULL, NULL, NULL, TRUE) == TRUE); fail_unless (gst_tag_parse_extended_comment ("foobar", NULL, NULL, NULL, TRUE) == FALSE); /* test non-strict mode (if there's no key, that's fine too) */ fail_unless (gst_tag_parse_extended_comment ("foobar", NULL, NULL, NULL, FALSE) == TRUE); fail_unless (gst_tag_parse_extended_comment ("[fr]bar", NULL, NULL, NULL, FALSE) == TRUE); key = val = lang = NULL; fail_unless (gst_tag_parse_extended_comment ("[fr]bar", &key, &lang, &val, FALSE) == TRUE); fail_unless (key == NULL); fail_unless (lang == NULL); fail_unless (val != NULL); fail_unless_equals_string (val, "[fr]bar"); g_free (key); g_free (lang); g_free (val); } GST_END_TEST; #define ASSERT_TAG_LIST_HAS_STRING(list,field,string) \ { \ gboolean got_match = FALSE; \ guint i, size; \ \ fail_unless (gst_tag_list_get_tag_size (list,field) > 0); \ size = gst_tag_list_get_tag_size (list,field); \ for (i = 0; i < size; ++i) { \ gchar *___s = NULL; \ \ fail_unless (gst_tag_list_get_string_index (list, field, i, &___s)); \ fail_unless (___s != NULL); \ if (g_str_equal (___s, string)) { \ got_match = TRUE; \ g_free (___s); \ break; \ } \ g_free (___s); \ } \ fail_unless (got_match); \ } #define ASSERT_TAG_LIST_HAS_UINT(list,field,num) \ { \ guint ___n; \ \ fail_unless (gst_tag_list_get_tag_size (list,field) > 0); \ fail_unless (gst_tag_list_get_tag_size (list,field) == 1); \ fail_unless (gst_tag_list_get_uint_index (list, field, 0, &___n)); \ fail_unless_equals_int (___n, num); \ } #define MATCH_DOUBLE(p1, p2) ((p1 < p2 + 1e-6) && (p2 < p1 + 1e-6)) #define ASSERT_TAG_LIST_HAS_DOUBLE(list,field,d) \ { \ gdouble ___d; \ \ fail_unless (gst_tag_list_get_tag_size (list,field) > 0); \ fail_unless (gst_tag_list_get_tag_size (list,field) == 1); \ fail_unless (gst_tag_list_get_double_index (list, field, 0, &___d)); \ fail_unless (MATCH_DOUBLE (d, ___d), \ "%f does not match expected %f", ___d, d); \ } GST_START_TEST (test_muscibrainz_tag_registration) { GstTagList *list; gst_tag_register_musicbrainz_tags (); list = gst_tag_list_new (); /* musicbrainz tags aren't registered yet */ gst_vorbis_tag_add (list, "MUSICBRAINZ_TRACKID", "123456"); gst_vorbis_tag_add (list, "MUSICBRAINZ_ARTISTID", "234567"); gst_vorbis_tag_add (list, "MUSICBRAINZ_ALBUMID", "345678"); gst_vorbis_tag_add (list, "MUSICBRAINZ_ALBUMARTISTID", "4567890"); gst_vorbis_tag_add (list, "MUSICBRAINZ_TRMID", "5678901"); /* MUSICBRAINZ_SORTNAME = GST_TAG_ARTIST_SORTNAME now */ gst_vorbis_tag_add (list, "MUSICBRAINZ_SORTNAME", "Five, 678901"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_TRACKID, "123456"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ARTISTID, "234567"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ALBUMID, "345678"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ALBUMARTISTID, "4567890"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_TRMID, "5678901"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST_SORTNAME, "Five, 678901"); gst_tag_list_free (list); } GST_END_TEST; /* is there an easier way to compare two structures / tagslists? */ static gboolean taglists_are_equal (const GstTagList * list_1, const GstTagList * list_2) { GstCaps *c_list_1 = gst_caps_new_empty (); GstCaps *c_list_2 = gst_caps_new_empty (); gboolean ret; gst_caps_append_structure (c_list_1, gst_structure_copy ((GstStructure *) list_1)); gst_caps_append_structure (c_list_2, gst_structure_copy ((GstStructure *) list_2)); ret = gst_caps_is_equal (c_list_2, c_list_1); gst_caps_unref (c_list_1); gst_caps_unref (c_list_2); return ret; } GST_START_TEST (test_vorbis_tags) { GstTagList *list; list = gst_tag_list_new (); /* NULL pointers aren't allowed */ ASSERT_CRITICAL (gst_vorbis_tag_add (NULL, "key", "value")); ASSERT_CRITICAL (gst_vorbis_tag_add (list, NULL, "value")); ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key", NULL)); /* must be UTF-8 */ ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key", "v\377lue")); ASSERT_CRITICAL (gst_vorbis_tag_add (list, "k\377y", "value")); /* key can't have a '=' in it */ ASSERT_CRITICAL (gst_vorbis_tag_add (list, "k=y", "value")); ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key=", "value")); /* should be allowed in values though */ gst_vorbis_tag_add (list, "keeey", "va=ue"); /* add some tags */ gst_vorbis_tag_add (list, "TITLE", "Too"); gst_vorbis_tag_add (list, "ALBUM", "Aoo"); gst_vorbis_tag_add (list, "ARTIST", "Alboo"); gst_vorbis_tag_add (list, "PERFORMER", "Perfoo"); gst_vorbis_tag_add (list, "COPYRIGHT", "Copyfoo"); gst_vorbis_tag_add (list, "DESCRIPTION", "Descoo"); gst_vorbis_tag_add (list, "LICENSE", "Licoo"); gst_vorbis_tag_add (list, "LICENSE", "http://creativecommons.org/licenses/by/3.0/"); gst_vorbis_tag_add (list, "LOCATION", "Bristol, UK"); gst_vorbis_tag_add (list, "ORGANIZATION", "Orgoo"); gst_vorbis_tag_add (list, "GENRE", "Goo"); gst_vorbis_tag_add (list, "CONTACT", "Coo"); gst_vorbis_tag_add (list, "COMMENT", "Stroodle is good"); gst_vorbis_tag_add (list, "COMMENT", "Peroxysulfid stroodles the brain"); gst_vorbis_tag_add (list, "TRACKNUMBER", "5"); gst_vorbis_tag_add (list, "TRACKTOTAL", "77"); gst_vorbis_tag_add (list, "DISCNUMBER", "1"); gst_vorbis_tag_add (list, "DISCTOTAL", "2"); gst_vorbis_tag_add (list, "DATE", "1954-12-31"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_TITLE, "Too"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ALBUM, "Aoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "Alboo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_PERFORMER, "Perfoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COPYRIGHT, "Copyfoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_DESCRIPTION, "Descoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LICENSE, "Licoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LICENSE_URI, "http://creativecommons.org/licenses/by/3.0/"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_GEO_LOCATION_NAME, "Bristol, UK"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ORGANIZATION, "Orgoo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_GENRE, "Goo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_CONTACT, "Coo"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COMMENT, "Peroxysulfid stroodles the brain"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COMMENT, "Stroodle is good"); ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_TRACK_NUMBER, 5); ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_TRACK_COUNT, 77); ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_ALBUM_VOLUME_NUMBER, 1); ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_ALBUM_VOLUME_COUNT, 2); { GDate *date = NULL; fail_unless (gst_tag_list_get_date (list, GST_TAG_DATE, &date)); fail_unless (date != NULL); fail_unless (g_date_get_day (date) == 31); fail_unless (g_date_get_month (date) == G_DATE_DECEMBER); fail_unless (g_date_get_year (date) == 1954); g_date_free (date); } /* unknown vorbis comments should go into a GST_TAG_EXTENDED_COMMENT */ gst_vorbis_tag_add (list, "CoEdSub_ID", "98172AF-973-10-B"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_EXTENDED_COMMENT, "CoEdSub_ID=98172AF-973-10-B"); gst_vorbis_tag_add (list, "RuBuWuHash", "1337BA42F91"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_EXTENDED_COMMENT, "RuBuWuHash=1337BA42F91"); gst_vorbis_tag_add (list, "REPLAYGAIN_REFERENCE_LOUDNESS", "89."); ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_REFERENCE_LEVEL, 89.); gst_vorbis_tag_add (list, "REPLAYGAIN_TRACK_GAIN", "+12.36"); ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_TRACK_GAIN, +12.36); gst_vorbis_tag_add (list, "REPLAYGAIN_TRACK_PEAK", "0.96349"); ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_TRACK_PEAK, 0.96349); gst_vorbis_tag_add (list, "REPLAYGAIN_ALBUM_GAIN", "+10.12"); ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_ALBUM_GAIN, +10.12); /* now check that we can parse floating point numbers with any separator * (',' or '.') regardless of the current locale */ gst_vorbis_tag_add (list, "REPLAYGAIN_ALBUM_PEAK", "0,98107"); ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_ALBUM_PEAK, 0.98107); gst_vorbis_tag_add (list, "LICENSE", "http://foo.com/license-1.html"); /* make sure we can convert back and forth without loss */ { GstTagList *new_list, *even_newer_list; GstBuffer *buf, *buf2; gchar *vendor_id = NULL; buf = gst_tag_list_to_vorbiscomment_buffer (list, (const guint8 *) "\003vorbis", 7, "libgstunittest"); fail_unless (buf != NULL); new_list = gst_tag_list_from_vorbiscomment_buffer (buf, (const guint8 *) "\003vorbis", 7, &vendor_id); fail_unless (new_list != NULL); fail_unless (vendor_id != NULL); g_free (vendor_id); vendor_id = NULL; GST_LOG ("new_list = %" GST_PTR_FORMAT, new_list); fail_unless (taglists_are_equal (list, new_list)); buf2 = gst_tag_list_to_vorbiscomment_buffer (new_list, (const guint8 *) "\003vorbis", 7, "libgstunittest"); fail_unless (buf2 != NULL); even_newer_list = gst_tag_list_from_vorbiscomment_buffer (buf2, (const guint8 *) "\003vorbis", 7, &vendor_id); fail_unless (even_newer_list != NULL); fail_unless (vendor_id != NULL); g_free (vendor_id); vendor_id = NULL; GST_LOG ("even_newer_list = %" GST_PTR_FORMAT, even_newer_list); fail_unless (taglists_are_equal (new_list, even_newer_list)); gst_tag_list_free (new_list); gst_tag_list_free (even_newer_list); gst_buffer_unref (buf); gst_buffer_unref (buf2); } /* there can only be one language per taglist ... */ gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "fr"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr"); gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "[fr]"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr"); gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "French [fr]"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr"); gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "[eng] English"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng"); gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "eng"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng"); gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "[eng]"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng"); /* free-form *sigh* */ gst_tag_list_free (list); list = gst_tag_list_new (); gst_vorbis_tag_add (list, "LANGUAGE", "English"); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "English"); /* now, while we still have a taglist, test _to_vorbiscomment_buffer() */ { GstBuffer *buf1, *buf2; ASSERT_CRITICAL (gst_tag_list_to_vorbiscomment_buffer (NULL, (const guint8 *) "x", 1, "x")); buf1 = gst_tag_list_to_vorbiscomment_buffer (list, NULL, 0, NULL); fail_unless (buf1 != NULL); buf2 = gst_tag_list_to_vorbiscomment_buffer (list, (const guint8 *) "foo", 3, NULL); fail_unless (buf2 != NULL); fail_unless (memcmp (GST_BUFFER_DATA (buf1), GST_BUFFER_DATA (buf2) + 3, GST_BUFFER_SIZE (buf1)) == 0); gst_buffer_unref (buf1); gst_buffer_unref (buf2); } gst_tag_list_free (list); /* make sure gst_tag_list_from_vorbiscomment_buffer() works with an * empty ID (for Speex) */ { const guint8 speex_comments_buf1[] = { 0x03, 0x00, 0x00, 0x00, 'f', 'o', 'o', 0x00, 0x00, 0x00, 0x00 }; GstBuffer *buf; gchar *vendor = NULL; buf = gst_buffer_new (); GST_BUFFER_DATA (buf) = (guint8 *) speex_comments_buf1; GST_BUFFER_SIZE (buf) = sizeof (speex_comments_buf1); /* make sure it doesn't memcmp over the end of the buffer */ fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf, (const guint8 *) "averylongstringbrownfoxjumpoverthefence", 39, &vendor) == NULL); fail_unless (vendor == NULL); /* make sure it bails out if the ID doesn't match */ fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "short", 4, &vendor) == NULL); fail_unless (vendor == NULL); /* now read properly */ list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, &vendor); fail_unless (vendor != NULL); fail_unless_equals_string (vendor, "foo"); fail_unless (list != NULL); fail_unless (gst_structure_n_fields ((GstStructure *) list) == 0); g_free (vendor); gst_tag_list_free (list); /* now again without vendor */ list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, NULL); fail_unless (list != NULL); fail_unless (gst_structure_n_fields ((GstStructure *) list) == 0); gst_tag_list_free (list); gst_buffer_unref (buf); } /* the same with an ID */ { const guint8 vorbis_comments_buf[] = { 0x03, 'v', 'o', 'r', 'b', 'i', 's', 0x03, 0x00, 0x00, 0x00, 'f', 'o', 'o', 0x01, 0x00, 0x00, 0x00, strlen ("ARTIST=foo bar"), 0x00, 0x00, 0x00, 'A', 'R', 'T', 'I', 'S', 'T', '=', 'f', 'o', 'o', ' ', 'b', 'a', 'r' }; GstBuffer *buf; gchar *vendor = NULL; buf = gst_buffer_new (); GST_BUFFER_DATA (buf) = (guint8 *) vorbis_comments_buf; GST_BUFFER_SIZE (buf) = sizeof (vorbis_comments_buf); /* make sure it doesn't memcmp over the end of the buffer */ fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf, (const guint8 *) "averylongstringbrownfoxjumpoverthefence", 39, &vendor) == NULL); fail_unless (vendor == NULL); /* make sure it bails out if the ID doesn't match */ fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "short", 4, &vendor) == NULL); fail_unless (vendor == NULL); /* now read properly */ list = gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7, &vendor); fail_unless (vendor != NULL); fail_unless_equals_string (vendor, "foo"); fail_unless (list != NULL); fail_unless (gst_structure_n_fields ((GstStructure *) list) == 1); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "foo bar"); g_free (vendor); gst_tag_list_free (list); /* now again without vendor */ list = gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7, NULL); fail_unless (list != NULL); fail_unless (gst_structure_n_fields ((GstStructure *) list) == 1); ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "foo bar"); gst_tag_list_free (list); gst_buffer_unref (buf); } /* check date with time */ { GDate *date = NULL; list = gst_tag_list_new (); gst_vorbis_tag_add (list, "DATE", "2006-09-25 22:02:38"); fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date)); fail_unless (date != NULL); fail_unless (g_date_get_day (date) == 25); fail_unless (g_date_get_month (date) == G_DATE_SEPTEMBER); fail_unless (g_date_get_year (date) == 2006); g_date_free (date); gst_tag_list_free (list); } /* check date with month/day of 00-00 */ { GDate *date = NULL; list = gst_tag_list_new (); gst_vorbis_tag_add (list, "DATE", "1992-00-00"); fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date)); fail_unless (date != NULL); fail_unless (g_date_get_year (date) == 1992); g_date_free (date); gst_tag_list_free (list); } /* check date with valid month, but day of 00 */ { GDate *date = NULL; list = gst_tag_list_new (); gst_vorbis_tag_add (list, "DATE", "1992-05-00"); fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date)); fail_unless (date != NULL); fail_unless (g_date_get_year (date) == 1992); fail_unless (g_date_get_month (date) == G_DATE_MAY); g_date_free (date); gst_tag_list_free (list); } } GST_END_TEST; GST_START_TEST (test_id3_tags) { guint i; fail_unless (gst_tag_id3_genre_count () > 0); for (i = 0; i < gst_tag_id3_genre_count (); ++i) { const gchar *genre; genre = gst_tag_id3_genre_get (i); fail_unless (genre != NULL); } { /* TODO: GstTagList *gst_tag_list_new_from_id3v1 (const guint8 *data) */ } /* gst_tag_from_id3_tag */ fail_unless (gst_tag_from_id3_tag ("TALB") != NULL); ASSERT_CRITICAL (gst_tag_from_id3_tag (NULL)); fail_unless (gst_tag_from_id3_tag ("R2D2") == NULL); fail_unless_equals_string (gst_tag_from_id3_tag ("WCOP"), GST_TAG_COPYRIGHT_URI); /* gst_tag_from_id3_user_tag */ ASSERT_CRITICAL (gst_tag_from_id3_user_tag (NULL, "foo")); ASSERT_CRITICAL (gst_tag_from_id3_user_tag ("foo", NULL)); fail_unless (gst_tag_from_id3_user_tag ("R2D2", "R2D2") == NULL); /* gst_tag_to_id3_tag */ ASSERT_CRITICAL (gst_tag_to_id3_tag (NULL)); fail_unless (gst_tag_to_id3_tag ("R2D2") == NULL); fail_unless (gst_tag_to_id3_tag (GST_TAG_ARTIST) != NULL); fail_unless_equals_string (gst_tag_to_id3_tag (GST_TAG_COPYRIGHT_URI), "WCOP"); fail_unless (GST_TYPE_TAG_IMAGE_TYPE != 0); fail_unless (g_type_name (GST_TYPE_TAG_IMAGE_TYPE) != NULL); } GST_END_TEST; GST_START_TEST (test_id3v1_utf8_tag) { const guint8 id3v1[128] = { /* marker */ 'T', 'A', 'G', /* title (30 bytes) */ 'D', 0xc3, 0xad, 'v', 'k', 'a', ' ', 's', ' ', 'p', 'e', 'r', 'l', 'a', 'm', 'i', ' ', 'v', 'e', ' ', 'v', 'l', 'a', 's', 'e', 'c', 'h', 0, 0, 0, /* artist (30 bytes) */ 'A', 'l', 'e', 0xc5, 0xa1, ' ', 'B', 'r', 'i', 'c', 'h', 't', 'a', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* album (30 bytes) */ 'B', 'e', 's', 't', ' ', 'o', 'f', ' ', '(', 'P', 'r', 'o', 's', 't', 0xc4, 0x9b, ' ', 0xc3, 0xba, 0xc5, 0xbe, 'a', 's', 'n', 0xc3, 0xbd, ')', 0, 0, 0, /* year (4 bytes) */ '2', '0', '0', '0', /* comment (28 bytes) */ '-', '-', '-', ' ', 0xc4, 0x8d, 'e', 's', 'k', 0xc3, 0xa9, ' ', 'p', 0xc3, 0xad, 's', 'n', 'i', 0xc4, 0x8d, 'k', 'y', ' ', '-', '-', '-', 0, 0, /* track number */ 0, 0, /* genre */ 0x11 }; GstTagList *tags; GDate *d; gchar *s; /* set this, to make sure UTF-8 strings are really interpreted properly * as UTF-8, regardless of the locale set */ g_setenv ("GST_ID3V1_TAG_ENCODING", "WINDOWS-1250", TRUE); tags = gst_tag_list_new_from_id3v1 (id3v1); fail_unless (tags != NULL); GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags); s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s)); fail_unless (s != NULL); fail_unless_equals_string (s, "Dívka s perlami ve vlasech"); g_free (s); s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &s)); fail_unless (s != NULL); fail_unless_equals_string (s, "Aleš Brichta"); g_free (s); s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &s)); fail_unless (s != NULL); fail_unless_equals_string (s, "Best of (Prostě úžasný)"); g_free (s); d = NULL; fail_unless (gst_tag_list_get_date (tags, GST_TAG_DATE, &d)); fail_unless (d != NULL); fail_unless_equals_int (g_date_get_year (d), 2000); g_date_free (d); d = NULL; gst_tag_list_free (tags); g_unsetenv ("GST_ID3V1_TAG_ENCODING"); } GST_END_TEST; GST_START_TEST (test_language_utils) { gchar **lang_codes, **c; #define ASSERT_STRINGS_EQUAL fail_unless_equals_string lang_codes = gst_tag_get_language_codes (); fail_unless (lang_codes != NULL); fail_unless (*lang_codes != NULL); for (c = lang_codes; c != NULL && *c != NULL; ++c) { const gchar *lang_name, *c1, *c2t, *c2b; lang_name = gst_tag_get_language_name (*c); fail_unless (lang_name != NULL); fail_unless (g_utf8_validate (lang_name, -1, NULL)); c1 = gst_tag_get_language_code_iso_639_1 (*c); fail_unless (c1 != NULL); fail_unless (g_utf8_validate (c1, -1, NULL)); c2t = gst_tag_get_language_code_iso_639_2T (*c); fail_unless (c2t != NULL); fail_unless (g_utf8_validate (c2t, -1, NULL)); c2b = gst_tag_get_language_code_iso_639_2B (*c); fail_unless (c2b != NULL); fail_unless (g_utf8_validate (c2b, -1, NULL)); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (*c), *c); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (c2t), *c); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (c2b), *c); GST_DEBUG ("[%s] %s %s %s : %s\n", *c, c1, c2t, c2b, lang_name); } g_strfreev (lang_codes); fail_unless (gst_tag_get_language_name ("de") != NULL); fail_unless (gst_tag_get_language_name ("deu") != NULL); fail_unless (gst_tag_get_language_name ("ger") != NULL); fail_unless_equals_string (gst_tag_get_language_name ("deu"), gst_tag_get_language_name ("ger")); fail_unless_equals_string (gst_tag_get_language_name ("de"), gst_tag_get_language_name ("ger")); fail_unless (gst_tag_get_language_name ("de") != gst_tag_get_language_name ("fr")); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("deu"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("de"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("ger"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("deu"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("de"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("ger"), "de"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("de"), "deu"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("deu"), "deu"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("ger"), "deu"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("de"), "ger"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("deu"), "ger"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("ger"), "ger"); } GST_END_TEST; GST_START_TEST (test_xmp_formatting) { GstTagList *list; GstBuffer *buf; const gchar *text; guint len; /* test data */ list = gst_tag_list_new_full (GST_TAG_TITLE, "test title", GST_TAG_DESCRIPTION, "test decription", GST_TAG_KEYWORDS, "keyword1", GST_TAG_KEYWORDS, "keyword2", NULL); buf = gst_tag_list_to_xmp_buffer (list, FALSE); fail_unless (buf != NULL); text = (const gchar *) GST_BUFFER_DATA (buf); len = GST_BUFFER_SIZE (buf); /* check the content */ fail_unless (g_strrstr_len (text, len, "test title<") != NULL); fail_unless (g_strrstr_len (text, len, ">test decription<") != NULL); fail_unless (g_strrstr_len (text, len, ">keyword1<") != NULL); fail_unless (g_strrstr_len (text, len, ">keyword2<") != NULL); fail_unless (g_strrstr_len (text, len, "" "" ""; const gchar *xmp_footer = "" "" "\n"; struct { const gchar *xmp_data; gint result_size; gint result_test; } test_data[] = { { "", -1, -1}, { "", 0, -1}, { "", 0, -1}, { "", 0, -1}, { "test", 1, 0}, { "", 1, 0}, { NULL, -1, -1} }; /* test data */ buf = gst_buffer_new (); i = 0; while (test_data[i].xmp_data) { GST_DEBUG ("trying test-data %u", i); text = g_strconcat (xmp_header, test_data[i].xmp_data, xmp_footer, NULL); GST_BUFFER_DATA (buf) = (guint8 *) text; GST_BUFFER_SIZE (buf) = strlen (text) + 1; list = gst_tag_list_from_xmp_buffer (buf); if (test_data[i].result_size >= 0) { fail_unless (list != NULL); result_size = gst_structure_n_fields ((GstStructure *) list); fail_unless (result_size == test_data[i].result_size); /* check the taglist content */ switch (test_data[i].result_test) { case 0: ASSERT_TAG_LIST_HAS_STRING (list, "description", "test"); break; default: break; } } if (list) gst_tag_list_free (list); g_free (text); i++; } gst_buffer_unref (buf); } GST_END_TEST; static void tag_list_equals (GstTagList * taglist, GstTagList * taglist2) { const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found; gint comparison; gint n_recv; gint n_sent; gint i, j; /* verify tags */ fail_unless (taglist2 != NULL); n_recv = gst_structure_n_fields (taglist2); n_sent = gst_structure_n_fields (taglist); fail_unless (n_recv == n_sent); fail_unless (n_sent > 0); /* FIXME: compare taglist values */ for (i = 0; i < n_sent; i++) { name_sent = gst_structure_nth_field_name (taglist, i); value_sent = gst_structure_get_value (taglist, name_sent); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_structure_nth_field_name (taglist2, j); if (!strcmp (name_sent, name_recv)) { value_recv = gst_structure_get_value (taglist2, name_recv); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } if (comparison != GST_VALUE_EQUAL && G_VALUE_HOLDS (value_sent, G_TYPE_DOUBLE)) { gdouble vs; gdouble vr; /* add some tolerance for doubles */ vs = g_value_get_double (value_sent); vr = g_value_get_double (value_recv); if (vr >= vs - 0.001 && vr <= vs + 0.001) comparison = GST_VALUE_EQUAL; } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } fail_unless (found, "tag item %s is lost", name_sent); } } static void do_xmp_tag_serialization_deserialization (GstTagList * taglist) { GstTagList *taglist2; GstBuffer *buf; buf = gst_tag_list_to_xmp_buffer (taglist, TRUE); taglist2 = gst_tag_list_from_xmp_buffer (buf); tag_list_equals (taglist, taglist2); gst_buffer_unref (buf); gst_tag_list_free (taglist2); } static void do_simple_xmp_tag_serialization_deserialization (const gchar * gsttag, GValue * value) { GstTagList *taglist = gst_tag_list_new (); gst_tag_list_add_value (taglist, GST_TAG_MERGE_REPLACE, gsttag, value); do_xmp_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); } GST_START_TEST (test_xmp_tags_serialization_deserialization) { GValue value = { 0 }; GDate *date; GstDateTime *datetime; g_value_init (&value, G_TYPE_STRING); g_value_set_static_string (&value, "my string"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_ARTIST, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_COPYRIGHT, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DESCRIPTION, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_KEYWORDS, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_TITLE, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_VIDEO_CODEC, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_COUNTRY, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CITY, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_SUBLOCATION, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DEVICE_MANUFACTURER, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DEVICE_MODEL, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_APPLICATION_NAME, &value); g_value_set_static_string (&value, "rotate-0"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-0"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-180"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-180"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-270"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-90"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-90"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-270"); do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_unset (&value); g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, 0.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LATITUDE, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, 10.5); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LATITUDE, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, -32.375); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LATITUDE, &value); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, 0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, 100); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, 500.25); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, -12.75); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, 0.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, 10.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, 786.125); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, -2.5); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, 0.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value); g_value_set_double (&value, 180.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value); g_value_set_double (&value, 359.99); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value); g_value_set_double (&value, 0.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value); g_value_set_double (&value, 90.0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value); g_value_set_double (&value, 359.99); do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_DATE); date = g_date_new_dmy (22, 3, 2010); gst_value_set_date (&value, date); g_date_free (date); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE, &value); g_value_unset (&value); g_value_init (&value, G_TYPE_UINT); g_value_set_uint (&value, 0); do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value); g_value_set_uint (&value, 100); do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value); g_value_set_uint (&value, 22); do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_DATE_TIME); datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.000125); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.000001); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.123456); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new (-3, 2010, 6, 22, 12, 5, 10.123456); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new (5, 2010, 6, 22, 12, 5, 10.123456); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); datetime = gst_date_time_new_local_time (2010, 12, 2, 12, 5, 10.000043); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); g_value_unset (&value); } GST_END_TEST; GST_START_TEST (test_xmp_compound_tags) { GstTagList *taglist = gst_tag_list_new (); gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_KEYWORDS, "k1", GST_TAG_KEYWORDS, "k2", GST_TAG_TITLE, "title", GST_TAG_KEYWORDS, "k3", NULL); do_xmp_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); } GST_END_TEST; GST_START_TEST (test_exif_parsing) { GstTagList *taglist; GstBuffer *buf; GstByteWriter writer; const gchar *str; gst_byte_writer_init (&writer); /* write the IFD */ /* 1 entry */ gst_byte_writer_put_uint16_le (&writer, 1); /* copyright tag */ /* tag id */ gst_byte_writer_put_uint16_le (&writer, 0x8298); /* tag type */ gst_byte_writer_put_uint16_le (&writer, 0x2); /* count */ gst_byte_writer_put_uint32_le (&writer, strlen ("my copyright") + 1); /* offset */ gst_byte_writer_put_uint32_le (&writer, 8 + 14); /* data */ gst_byte_writer_put_string (&writer, "my copyright"); buf = gst_byte_writer_reset_and_get_buffer (&writer); taglist = gst_tag_list_from_exif_buffer (buf, G_LITTLE_ENDIAN, 8); fail_unless (gst_structure_n_fields (taglist) == 1); fail_unless (gst_structure_has_field_typed (taglist, GST_TAG_COPYRIGHT, G_TYPE_STRING)); str = gst_structure_get_string (taglist, GST_TAG_COPYRIGHT); fail_unless (strcmp (str, "my copyright") == 0); gst_tag_list_free (taglist); gst_buffer_unref (buf); } GST_END_TEST; static void do_exif_tag_serialization_deserialization (GstTagList * taglist) { GstTagList *taglist2; GstBuffer *buf; /* LE */ buf = gst_tag_list_to_exif_buffer (taglist, G_LITTLE_ENDIAN, 0); taglist2 = gst_tag_list_from_exif_buffer (buf, G_LITTLE_ENDIAN, 0); gst_buffer_unref (buf); tag_list_equals (taglist, taglist2); gst_tag_list_free (taglist2); /* BE */ buf = gst_tag_list_to_exif_buffer (taglist, G_BIG_ENDIAN, 0); taglist2 = gst_tag_list_from_exif_buffer (buf, G_BIG_ENDIAN, 0); gst_buffer_unref (buf); tag_list_equals (taglist, taglist2); gst_tag_list_free (taglist2); /* APP1 */ buf = gst_tag_list_to_exif_buffer_with_tiff_header (taglist); taglist2 = gst_tag_list_from_exif_buffer_with_tiff_header (buf); gst_buffer_unref (buf); tag_list_equals (taglist, taglist2); gst_tag_list_free (taglist2); } static void do_simple_exif_tag_serialization_deserialization (const gchar * gsttag, GValue * value) { GstTagList *taglist = gst_tag_list_new (); gst_tag_list_add_value (taglist, GST_TAG_MERGE_REPLACE, gsttag, value); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); } /* * Adds tags from multiple ifd tables and tries serializing them */ GST_START_TEST (test_exif_multiple_tags) { GstTagList *taglist; GstDateTime *datetime; GValue value = { 0 }; gst_tag_register_musicbrainz_tags (); taglist = gst_tag_list_new_full (GST_TAG_ARTIST, "artist", GST_TAG_DEVICE_MANUFACTURER, "make", GST_TAG_DEVICE_MODEL, "model", GST_TAG_GEO_LOCATION_LATITUDE, 45.5, GST_TAG_GEO_LOCATION_LONGITUDE, -10.25, GST_TAG_IMAGE_HORIZONTAL_PPI, 300.0, GST_TAG_IMAGE_VERTICAL_PPI, 300.0, NULL); g_value_init (&value, GST_TYPE_DATE_TIME); datetime = gst_date_time_new_local_time (2010, 6, 22, 12, 5, 10); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); gst_tag_list_add_value (taglist, GST_TAG_MERGE_APPEND, GST_TAG_DATE_TIME, &value); g_value_unset (&value); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); } GST_END_TEST; GST_START_TEST (test_exif_tags_serialization_deserialization) { GValue value = { 0 }; GstDateTime *datetime = NULL; GstBuffer *buf = NULL; gint i; GstTagList *taglist; gst_tag_register_musicbrainz_tags (); g_value_init (&value, G_TYPE_STRING); g_value_set_static_string (&value, "my string"); do_simple_exif_tag_serialization_deserialization (GST_TAG_COPYRIGHT, &value); g_value_set_static_string (&value, "ty"); do_simple_exif_tag_serialization_deserialization (GST_TAG_ARTIST, &value); g_value_set_static_string (&value, "Company Software 1.2b (info)"); do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_NAME, &value); /* image orientation tests */ g_value_set_static_string (&value, "rotate-0"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-0"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-180"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-180"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-270"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-90"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "flip-rotate-90"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); g_value_set_static_string (&value, "rotate-270"); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION, &value); /* exposure program */ g_value_set_static_string (&value, "undefined"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "manual"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "normal"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "aperture-priority"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "shutter-priority"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "creative"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "action"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "portrait"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); g_value_set_static_string (&value, "landscape"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value); /* exposure mode */ g_value_set_static_string (&value, "auto-exposure"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_MODE, &value); g_value_set_static_string (&value, "manual-exposure"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_MODE, &value); g_value_set_static_string (&value, "auto-bracket"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_EXPOSURE_MODE, &value); /* scene capture type */ g_value_set_static_string (&value, "standard"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value); g_value_set_static_string (&value, "portrait"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value); g_value_set_static_string (&value, "landscape"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value); g_value_set_static_string (&value, "night-scene"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value); g_value_set_static_string (&value, "none"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value); g_value_set_static_string (&value, "high-gain-up"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value); g_value_set_static_string (&value, "low-gain-up"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value); g_value_set_static_string (&value, "high-gain-down"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value); g_value_set_static_string (&value, "low-gain-down"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value); g_value_set_static_string (&value, "auto"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_WHITE_BALANCE, &value); g_value_set_static_string (&value, "manual"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_WHITE_BALANCE, &value); g_value_set_static_string (&value, "normal"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST, &value); g_value_set_static_string (&value, "hard"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST, &value); g_value_set_static_string (&value, "soft"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST, &value); g_value_set_static_string (&value, "normal"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SATURATION, &value); g_value_set_static_string (&value, "low-saturation"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SATURATION, &value); g_value_set_static_string (&value, "high-saturation"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SATURATION, &value); g_value_set_static_string (&value, "normal"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS, &value); g_value_set_static_string (&value, "hard"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS, &value); g_value_set_static_string (&value, "soft"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS, &value); g_value_set_static_string (&value, "unknown"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "average"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "center-weighted-average"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "spot"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "multi-spot"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "pattern"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "partial"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "other"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_METERING_MODE, &value); g_value_set_static_string (&value, "dsc"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE, &value); g_value_set_static_string (&value, "other"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE, &value); g_value_set_static_string (&value, "transparent-scanner"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE, &value); g_value_set_static_string (&value, "reflex-scanner"); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE, &value); g_value_unset (&value); g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, 30.5); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LATITUDE, &value); g_value_set_double (&value, -12.125); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LATITUDE, &value); g_value_set_double (&value, 0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, 65.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, -0.75); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_LONGITUDE, &value); g_value_set_double (&value, 0.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value); g_value_set_double (&value, 180.5); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value); g_value_set_double (&value, 0.12345); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value); g_value_set_double (&value, 359.9); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value); g_value_set_double (&value, 0.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, 321.456); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, -12.56); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_ELEVATION, &value); g_value_set_double (&value, 0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, 100 / 3.6); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value); g_value_set_double (&value, 0); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, &value); g_value_set_double (&value, 50.25); do_simple_exif_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, &value); g_value_set_double (&value, 0); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value); g_value_set_double (&value, 2.5); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value); g_value_set_double (&value, 8.75); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value); g_value_set_double (&value, 20.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_FOCAL_LENGTH, &value); g_value_set_double (&value, 5.5); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_FOCAL_LENGTH, &value); g_value_set_double (&value, 16); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_FOCAL_RATIO, &value); g_value_set_double (&value, 2.7); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_FOCAL_LENGTH, &value); g_value_set_double (&value, 96.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_HORIZONTAL_PPI, &value); g_value_set_double (&value, 300.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_HORIZONTAL_PPI, &value); g_value_set_double (&value, 87.5); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_VERTICAL_PPI, &value); g_value_set_double (&value, 600.0); do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_VERTICAL_PPI, &value); g_value_unset (&value); g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, 400); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_ISO_SPEED, &value); g_value_set_int (&value, 1600); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_ISO_SPEED, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_DATE_TIME); datetime = gst_date_time_new_local_time (2010, 6, 22, 12, 5, 10); g_value_set_boxed (&value, datetime); gst_date_time_unref (datetime); do_simple_exif_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_BUFFER); buf = gst_buffer_new_and_alloc (1024); for (i = 0; i < 1024; i++) GST_BUFFER_DATA (buf)[i] = i % 255; gst_value_set_buffer (&value, buf); gst_buffer_unref (buf); do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_DATA, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_FRACTION); gst_value_set_fraction (&value, 1, 1); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHUTTER_SPEED, &value); gst_value_set_fraction (&value, 1, 30); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHUTTER_SPEED, &value); gst_value_set_fraction (&value, 1, 200); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHUTTER_SPEED, &value); gst_value_set_fraction (&value, 1, 8000); do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHUTTER_SPEED, &value); g_value_unset (&value); /* flash is a little bit more tricky, because 2 tags are merged into 1 in * exif */ taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, FALSE, GST_TAG_CAPTURING_FLASH_MODE, "auto", NULL); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, TRUE, GST_TAG_CAPTURING_FLASH_MODE, "auto", NULL); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, FALSE, GST_TAG_CAPTURING_FLASH_MODE, "never", NULL); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, TRUE, GST_TAG_CAPTURING_FLASH_MODE, "always", NULL); do_exif_tag_serialization_deserialization (taglist); gst_tag_list_free (taglist); } GST_END_TEST; static Suite * tag_suite (void) { Suite *s = suite_create ("tag support library"); TCase *tc_chain = tcase_create ("general"); suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_muscibrainz_tag_registration); tcase_add_test (tc_chain, test_parse_extended_comment); tcase_add_test (tc_chain, test_vorbis_tags); tcase_add_test (tc_chain, test_id3_tags); tcase_add_test (tc_chain, test_id3v1_utf8_tag); tcase_add_test (tc_chain, test_language_utils); tcase_add_test (tc_chain, test_xmp_formatting); tcase_add_test (tc_chain, test_xmp_parsing); tcase_add_test (tc_chain, test_xmp_tags_serialization_deserialization); tcase_add_test (tc_chain, test_xmp_compound_tags); tcase_add_test (tc_chain, test_exif_parsing); tcase_add_test (tc_chain, test_exif_tags_serialization_deserialization); tcase_add_test (tc_chain, test_exif_multiple_tags); return s; } int main (int argc, char **argv) { int nf; Suite *s = tag_suite (); SRunner *sr = srunner_create (s); gst_check_init (&argc, &argv); srunner_run_all (sr, CK_NORMAL); nf = srunner_ntests_failed (sr); srunner_free (sr); return nf; }