diff options
author | Michael Smith <msmith@xiph.org> | 2006-02-24 19:07:10 +0000 |
---|---|---|
committer | Michael Smith <msmith@xiph.org> | 2006-02-24 19:07:10 +0000 |
commit | 73ce8c5b9e9a9cb27c1307dbfee300939265650c (patch) | |
tree | 207f645f3849f86026894e7411d9335353a12e53 /tests | |
parent | dd8f37faac9ea109550d630f4d7dcbf295cd5fc1 (diff) |
Add Annodex elements from Alessendro Decina: skeleton and CMML.
Original commit message from CVS:
* configure.ac:
* docs/plugins/gst-plugins-good-plugins-sections.txt:
* ext/Makefile.am:
* ext/annodex/Makefile.am:
* ext/annodex/gstannodex.c:
* ext/annodex/gstannodex.h:
* ext/annodex/gstcmmldec.c:
* ext/annodex/gstcmmldec.h:
* ext/annodex/gstcmmlenc.c:
* ext/annodex/gstcmmlenc.h:
* ext/annodex/gstcmmlparser.c:
* ext/annodex/gstcmmlparser.h:
* ext/annodex/gstcmmltag.c:
* ext/annodex/gstcmmltag.h:
* ext/annodex/gstcmmlutils.c:
* ext/annodex/gstcmmlutils.h:
* ext/annodex/gstskeldec.c:
* ext/annodex/gstskeldec.h:
* ext/annodex/gstskeltag.c:
* ext/annodex/gstskeltag.h:
* tests/check/Makefile.am:
* tests/check/elements/cmmldec.c:
* tests/check/elements/cmmlenc.c:
* tests/check/elements/skeldec.c:
Add Annodex elements from Alessendro Decina: skeleton and CMML.
Includes tests & docs, oh my! Passes Thomas's -good checklist
entirely. Wow.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/check/Makefile.am | 5 | ||||
-rw-r--r-- | tests/check/elements/cmmldec.c | 409 | ||||
-rw-r--r-- | tests/check/elements/cmmlenc.c | 361 | ||||
-rw-r--r-- | tests/check/elements/skeldec.c | 258 |
4 files changed, 1032 insertions, 1 deletions
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 4826e4ec..70a7fbfe 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -19,7 +19,10 @@ TESTS = $(check_PROGRAMS) check_PROGRAMS = \ elements/level \ - elements/matroskamux + elements/matroskamux \ + elements/cmmldec \ + elements/cmmlenc \ + elements/skeldec # these tests don't even pass diff --git a/tests/check/elements/cmmldec.c b/tests/check/elements/cmmldec.c new file mode 100644 index 00000000..f2498d22 --- /dev/null +++ b/tests/check/elements/cmmldec.c @@ -0,0 +1,409 @@ +/* + * cmmldec.c - GStreamer CMML decoder test suite + * Copyright (C) 2005 Alessandro Decina + * + * Authors: + * Alessandro Decina <alessandro@nnva.org> + * + * 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. + */ + +#include <gst/check/gstcheck.h> + +#define SINK_CAPS "text/xml" +#define SRC_CAPS "text/x-cmml" + +#define IDENT_HEADER \ + "CMML\x00\x00\x00\x00"\ + "\x03\x00\x00\x00"\ + "\x01\x00\x00\x00\x00\x00\x00\x00"\ + "\xe8\x03\x00\x00\x00\x00\x00\x00"\ + "\x20" + +#define XML_PREAMBLE \ + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"\ + "<!DOCTYPE cmml SYSTEM \"cmml.dtd\">\n"\ + +#define PREAMBLE \ + XML_PREAMBLE "<?cmml?>" + +#define PREAMBLE_DECODED \ + XML_PREAMBLE "<cmml >" + +#define HEAD_TAG \ + "<head>"\ + "<title>The Research Hunter</title>"\ + "<meta name=\"DC.audience\" content=\"General\"/>"\ + "<meta name=\"DC.author\" content=\"CSIRO Publishing\"/>"\ + "<meta name=\"DC.format\" content=\"video\"/>"\ + "<meta name=\"DC.language\" content=\"English\"/>"\ + "<meta name=\"DC.publisher\" content=\"CSIRO Australia\"/>"\ + "</head>" + +#define HEAD_TAG_DECODED HEAD_TAG + +#define CLIP_TEMPLATE \ + "<clip id=\"%s\" track=\"%s\">"\ + "<a href=\"http://www.csiro.au/\">http://www.csiro.au</a>"\ + "<img src=\"images/index1.jpg\"/>"\ + "<desc>Welcome to CSIRO</desc>"\ + "<meta name=\"test\" content=\"test content\"/>"\ + "</clip>" + +#define CLIP_TEMPLATE_DECODED \ + "<clip id=\"%s\" track=\"%s\" start=\"%s\">"\ + "<a href=\"http://www.csiro.au/\">http://www.csiro.au</a>"\ + "<img src=\"images/index1.jpg\"/>"\ + "<desc>Welcome to CSIRO</desc>"\ + "<meta name=\"test\" content=\"test content\"/>"\ + "</clip>" + +#define END_TAG \ + "</cmml>" + +GList *buffers; +GList *current_buf = NULL; +gint64 granulerate; +guint8 granuleshift; + +GstPad *srcpad, *sinkpad; + +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (SINK_CAPS) + ); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (SRC_CAPS) + ); + +static GstBuffer * +buffer_new (const gchar * buffer_data, guint size) +{ + GstBuffer *buffer; + GstCaps *caps; + + buffer = gst_buffer_new_and_alloc (size); + memcpy (GST_BUFFER_DATA (buffer), buffer_data, size); + caps = gst_caps_from_string (SRC_CAPS); + gst_buffer_set_caps (buffer, caps); + gst_caps_unref (caps); + + return buffer; +} + +static void +buffer_unref (void *buffer, void *user_data) +{ + ASSERT_OBJECT_REFCOUNT (buffer, "buf", 1); + gst_buffer_unref (GST_BUFFER (buffer)); +} + +GstElement * +setup_cmmldec () +{ + GstElement *cmmldec; + GstBus *bus; + + GST_DEBUG ("setup_cmmldec"); + cmmldec = gst_check_setup_element ("cmmldec"); + srcpad = gst_check_setup_src_pad (cmmldec, &srctemplate, NULL); + sinkpad = gst_check_setup_sink_pad (cmmldec, &sinktemplate, NULL); + + bus = gst_bus_new (); + gst_element_set_bus (cmmldec, bus); + + fail_unless (gst_element_set_state (cmmldec, + GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, + "could not set to playing"); + + granulerate = GST_SECOND / 1000; + granuleshift = 32; + buffers = NULL; + + return cmmldec; +} + +static void +cleanup_cmmldec (GstElement * cmmldec) +{ + GstBus *bus; + + g_list_foreach (buffers, buffer_unref, NULL); + g_list_free (buffers); + + bus = GST_ELEMENT_BUS (cmmldec); + gst_bus_set_flushing (bus, TRUE); + gst_object_unref (bus); + + GST_DEBUG ("cleanup_cmmldec"); + gst_check_teardown_src_pad (cmmldec); + gst_check_teardown_sink_pad (cmmldec); + gst_check_teardown_element (cmmldec); +} + +static void +check_output_buffer_is_equal (const gchar * name, + const gchar * data, gint refcount) +{ + GstBuffer *buffer = GST_BUFFER (current_buf->data); + + ASSERT_OBJECT_REFCOUNT (buffer, name, refcount); + fail_unless (memcmp (GST_BUFFER_DATA (buffer), data, + GST_BUFFER_SIZE (buffer)) == 0, + "'%s' (%s) is not equal to (%s)", name, GST_BUFFER_DATA (buffer), data); +} + +static void +push_data (const gchar * name, + const gchar * data, gint size, gint64 granulepos, + GstFlowReturn expected_return) +{ + GstBuffer *buffer; + GstFlowReturn res; + + buffer = buffer_new (data, size); + GST_BUFFER_OFFSET_END (buffer) = granulepos; + res = gst_pad_push (srcpad, buffer); + fail_unless (res == expected_return, + "pushing %s returned %d not %d", name, res, expected_return); +} + +static void +check_headers () +{ + /* push the ident header */ + push_data ("ident-header", IDENT_HEADER, 29, 0, GST_FLOW_OK); + /* push the cmml start tag */ + push_data ("preamble", PREAMBLE, strlen (PREAMBLE), 0, GST_FLOW_OK); + /* push the head tag */ + push_data ("head", HEAD_TAG, strlen (HEAD_TAG), 0, GST_FLOW_OK); + + current_buf = buffers; + fail_unless_equals_int (g_list_length (current_buf), 2); + + /* check the preamble */ + check_output_buffer_is_equal ("cmml-preamble-buffer", PREAMBLE_DECODED, 1); + + /* check the decoded head tag */ + current_buf = current_buf->next; + check_output_buffer_is_equal ("head-tag-buffer", HEAD_TAG_DECODED, 1); +} + +static void +push_clip (const gchar * name, const gchar * track, GstClockTime prev, + GstClockTime start, GstClockTime end, GstFlowReturn expected_return) +{ + gchar *clip; + gint64 keyindex, keyoffset, granulepos; + + if (track == NULL) + track = "default"; + + keyindex = prev / granulerate << granuleshift; + keyoffset = (start - prev) / granulerate; + granulepos = keyindex + keyoffset; + + clip = g_strdup_printf (CLIP_TEMPLATE, name, track); + push_data (name, clip, strlen (clip), granulepos, expected_return); + g_free (clip); +} + +static void +check_clip (const gchar * name, const gchar * track, + const gchar * start, const gchar * end) +{ + gchar *decoded_clip; + + if (track == NULL) + track = "default"; + + current_buf = current_buf->next; + fail_unless (g_list_length (current_buf)); + decoded_clip = g_strdup_printf (CLIP_TEMPLATE_DECODED, name, track, start); + check_output_buffer_is_equal (name, decoded_clip, 1); + g_free (decoded_clip); +} + +static void +check_end () +{ + current_buf = current_buf->next; + check_output_buffer_is_equal ("cmml-end-tag", END_TAG, 1); +} + +GST_START_TEST (test_dec) +{ + GstElement *cmmldec; + + cmmldec = setup_cmmldec (); + + check_headers (); + + push_clip ("clip-1", "default", + 0, 1 * GST_SECOND + 234 * GST_MSECOND, 0, GST_FLOW_OK); + push_clip ("clip-2", "othertrack", + 0, 4 * GST_SECOND + 321 * GST_MSECOND, 0, GST_FLOW_OK); + push_clip ("clip-3", "default", + 1 * GST_SECOND + 234 * GST_MSECOND, + ((100 * 3600) + (59 * 60) + 59) * GST_SECOND + 678 * GST_MSECOND, 0, + GST_FLOW_OK); + /* send EOS to flush clip-2 and clip-3 */ + gst_pad_send_event (GST_PAD_PEER (srcpad), gst_event_new_eos ()); + + printf ("Check1\n"); + check_clip ("clip-1", "default", "0:00:01.234", NULL); + printf ("Check2\n"); + check_clip ("clip-2", "othertrack", "0:00:04.321", NULL); + printf ("Check3\n"); + check_clip ("clip-3", "default", "100:59:59.678", NULL); + check_end (); + + cleanup_cmmldec (cmmldec); +} + +GST_END_TEST; + +GST_START_TEST (test_tags) +{ + GstElement *cmmldec; + GstBus *bus; + GstMessage *message; + GstTagList *tags; + const GValue *tag_val; + GObject *tag; + gchar *title, *base; + gboolean empty; + gchar *id, *track; + gint64 start_time, end_time; + gchar *anchor_href, *anchor_text; + gchar *img_src, *img_alt; + gchar *desc; + GValueArray *meta; + + cmmldec = setup_cmmldec (); + bus = gst_element_get_bus (cmmldec); + + check_headers (); + + /* read the GstCmmlTagHead tag */ + message = gst_bus_poll (bus, GST_MESSAGE_TAG, -1); + fail_unless (message != NULL); + + gst_message_parse_tag (message, &tags); + fail_unless (tags != NULL); + + tag_val = gst_tag_list_get_value_index (tags, GST_TAG_CMML_HEAD, 0); + fail_unless (tag_val != NULL); + + tag = g_value_get_object (tag_val); + fail_unless (tags != NULL); + + g_object_get (tag, "title", &title, "base-uri", &base, "meta", &meta, NULL); + fail_unless_equals_string ("The Research Hunter", title); + fail_unless (base == NULL); + fail_unless (meta != NULL); + fail_unless_equals_int (meta->n_values, 10); + + gst_message_unref (message); + gst_tag_list_free (tags); + g_free (title); + g_free (base); + g_value_array_free (meta); + + push_clip ("clip-1", "default", + 0, 1 * GST_SECOND + 234 * GST_MSECOND, 0, GST_FLOW_OK); + + /* read the GstCmmlTagClip */ + message = gst_bus_poll (bus, GST_MESSAGE_TAG, -1); + fail_unless (message != NULL); + + gst_message_parse_tag (message, &tags); + fail_unless (tags != NULL); + + tag_val = gst_tag_list_get_value_index (tags, GST_TAG_CMML_CLIP, 0); + fail_unless (tag_val != NULL); + + tag = g_value_get_object (tag_val); + fail_unless (tag != NULL); + + g_object_get (tag, "id", &id, "empty", &empty, "track", &track, + "start-time", &start_time, "end-time", &end_time, + "anchor-uri", &anchor_href, "anchor-text", &anchor_text, + "img-uri", &img_src, "img-alt", &img_alt, + "description", &desc, "meta", &meta, NULL); + + fail_unless (empty == FALSE); + fail_unless_equals_string (id, "clip-1"); + fail_unless_equals_string (track, "default"); + fail_unless_equals_int (start_time, 1 * GST_SECOND + 234 * GST_MSECOND); + fail_unless_equals_uint64 (end_time, GST_CLOCK_TIME_NONE); + fail_unless_equals_string (anchor_href, "http://www.csiro.au/"); + fail_unless_equals_string (anchor_text, "http://www.csiro.au"); + fail_unless_equals_string (img_src, "images/index1.jpg"); + fail_unless (img_alt == NULL); + fail_unless_equals_string (desc, "Welcome to CSIRO"); + fail_unless (meta != NULL); + fail_unless_equals_int (meta->n_values, 2); + + g_free (id); + g_free (track); + g_free (anchor_href); + g_free (anchor_text); + g_free (img_src); + g_free (img_alt); + g_free (desc); + g_value_array_free (meta); + gst_tag_list_free (tags); + gst_message_unref (message); + gst_object_unref (bus); + cleanup_cmmldec (cmmldec); +} + +GST_END_TEST; + +Suite * +cmmldec_suite () +{ + Suite *s = suite_create ("cmmldec"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_dec); + tcase_add_test (tc_chain, test_tags); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = cmmldec_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; +} diff --git a/tests/check/elements/cmmlenc.c b/tests/check/elements/cmmlenc.c new file mode 100644 index 00000000..da01984b --- /dev/null +++ b/tests/check/elements/cmmlenc.c @@ -0,0 +1,361 @@ +/* + * cmmlenc.c - GStreamer CMML decoder test suite + * Copyright (C) 2005 Alessandro Decina + * + * Authors: + * Alessandro Decina <alessandro@nnva.org> + * + * 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. + */ + +#include <gst/check/gstcheck.h> + +#define SINK_CAPS "text/x-cmml" +#define SRC_CAPS "text/xml" + +#define IDENT_HEADER \ + "CMML\x00\x00\x00\x00"\ + "\x03\x00\x00\x00"\ + "\x01\x00\x00\x00\x00\x00\x00\x00"\ + "\xe8\x03\x00\x00\x00\x00\x00\x00"\ + "\x20" + +#define XML_PREAMBLE \ + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"\ + "<!DOCTYPE cmml SYSTEM \"cmml.dtd\">\n" + +#define START_TAG \ + "<cmml>" + +#define PROCESSING_INSTRUCTION \ + "<?cmml ?>" + +#define PREAMBLE \ + XML_PREAMBLE START_TAG + +#define PREAMBLE_ENCODED \ + XML_PREAMBLE PROCESSING_INSTRUCTION + +#define STREAM_TAG \ + "<stream timebase=\"10\">"\ + "<import src=\"test.ogg\"/>"\ + "<import src=\"test1.ogg\"/>"\ + "</stream>" + +#define STREAM_TAG_ENCODED STREAM_TAG + +#define HEAD_TAG \ + "<head>"\ + "<title>The Research Hunter</title>"\ + "<meta name=\"DC.audience\" content=\"General\"/>"\ + "<meta name=\"DC.author\" content=\"CSIRO Publishing\"/>"\ + "<meta name=\"DC.format\" content=\"video\"/>"\ + "<meta name=\"DC.language\" content=\"English\"/>"\ + "<meta name=\"DC.publisher\" content=\"CSIRO Australia\"/>"\ + "</head>" + +#define HEAD_TAG_ENCODED HEAD_TAG + +#define END_TAG \ + "</cmml>" + +#define CLIP_TEMPLATE \ + "<clip id=\"%s\" track=\"%s\" start=\"%s\">"\ + "<a href=\"http://www.annodex.org/\">http://www.annodex.org</a>"\ + "<img src=\"images/index.jpg\"/>"\ + "<desc>Annodex Foundation</desc>"\ + "<meta name=\"test\" content=\"test content\"/>"\ + "</clip>" + +#define CLIP_TEMPLATE_ENCODED \ + "<clip id=\"%s\" track=\"%s\">"\ + "<a href=\"http://www.annodex.org/\">http://www.annodex.org</a>"\ + "<img src=\"images/index.jpg\"/>"\ + "<desc>Annodex Foundation</desc>"\ + "<meta name=\"test\" content=\"test content\"/>"\ + "</clip>" + +GList *buffers; +GList *current_buf = NULL; +guint64 granulerate; +guint8 granuleshift; + +GstPad *srcpad, *sinkpad; + +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (SINK_CAPS) + ); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (SRC_CAPS) + ); + +GstBuffer * +buffer_new (const gchar * buffer_data, guint size) +{ + GstBuffer *buffer; + GstCaps *caps; + + buffer = gst_buffer_new_and_alloc (size); + memcpy (GST_BUFFER_DATA (buffer), buffer_data, size); + caps = gst_caps_from_string (SRC_CAPS); + gst_buffer_set_caps (buffer, caps); + gst_caps_unref (caps); + + return buffer; +} + +static void +buffer_unref (void *buffer, void *user_data) +{ + gst_buffer_unref (GST_BUFFER (buffer)); +} + +GstElement * +setup_cmmlenc () +{ + GstElement *cmmlenc; + GstBus *bus; + guint64 granulerate_n, granulerate_d; + + GST_DEBUG ("setup_cmmlenc"); + + cmmlenc = gst_check_setup_element ("cmmlenc"); + srcpad = gst_check_setup_src_pad (cmmlenc, &srctemplate, NULL); + sinkpad = gst_check_setup_sink_pad (cmmlenc, &sinktemplate, NULL); + + bus = gst_bus_new (); + gst_element_set_bus (cmmlenc, bus); + + fail_unless (gst_element_set_state (cmmlenc, + GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, + "could not set to playing"); + + g_object_get (cmmlenc, "granule-rate-numerator", &granulerate_n, + "granule-rate-denominator", &granulerate_d, + "granule-shift", &granuleshift, NULL); + + granulerate = GST_SECOND * granulerate_n / granulerate_d; + buffers = NULL; + return cmmlenc; +} + +static void +cleanup_cmmlenc (GstElement * cmmlenc) +{ + GstBus *bus; + + /* free encoded buffers */ + g_list_foreach (buffers, buffer_unref, NULL); + g_list_free (buffers); + buffers = NULL; + + bus = GST_ELEMENT_BUS (cmmlenc); + gst_bus_set_flushing (bus, TRUE); + gst_object_unref (bus); + + GST_DEBUG ("cleanup_cmmlenc"); + gst_check_teardown_src_pad (cmmlenc); + gst_check_teardown_sink_pad (cmmlenc); + gst_check_teardown_element (cmmlenc); +} + +static void +check_output_buffer_is_equal (const gchar * name, + const gchar * data, gint refcount) +{ + GstBuffer *buffer = GST_BUFFER (current_buf->data); + + ASSERT_OBJECT_REFCOUNT (buffer, name, refcount); + fail_unless (memcmp (GST_BUFFER_DATA (buffer), data, + GST_BUFFER_SIZE (buffer)) == 0, + "'%s' (%s) is not equal to (%s)", name, GST_BUFFER_DATA (buffer), data); +} + +static void +push_data (const gchar * name, + const gchar * data, gint size, GstFlowReturn expected_return) +{ + GstBuffer *buffer; + GstFlowReturn res; + + buffer = buffer_new (data, size); + res = gst_pad_push (srcpad, buffer); + fail_unless (res == expected_return, + "pushing %s returned %d not %d", name, res, expected_return); +} + +static void +check_headers () +{ + /* push the cmml start tag */ + push_data ("preamble", PREAMBLE, strlen (PREAMBLE), GST_FLOW_OK); + /* push the stream tag */ + push_data ("stream", STREAM_TAG, strlen (STREAM_TAG), GST_FLOW_OK); + /* push the head tag */ + push_data ("head", HEAD_TAG, strlen (HEAD_TAG), GST_FLOW_OK); + + /* should output the cmml ident header and the cmml start tag transformed + * into a processing instruction */ + current_buf = buffers; + fail_unless_equals_int (g_list_length (current_buf), 3); + + /* check the ident header */ + check_output_buffer_is_equal ("cmml-ident-buffer", IDENT_HEADER, 2); + + /* check the cmml processing instruction */ + current_buf = current_buf->next; + check_output_buffer_is_equal ("cmml-preamble-buffer", PREAMBLE_ENCODED, 2); + + /* check the encoded head tag */ + current_buf = current_buf->next; + check_output_buffer_is_equal ("head-tag-buffer", HEAD_TAG_ENCODED, 2); +} + +static void +push_clip (const gchar * name, const gchar * track, + const gchar * start, const gchar * end, GstFlowReturn expected_return) +{ + gchar *clip; + + if (track == NULL) + track = "default"; + + clip = g_strdup_printf (CLIP_TEMPLATE, name, track, start, end); + push_data (name, clip, strlen (clip), expected_return); + g_free (clip); +} + +static void +check_clip (const gchar * name, const gchar * track, + GstClockTime start, GstClockTime prev) +{ + gchar *encoded_clip; + GstBuffer *buffer; + gint64 keyindex, keyoffset, granulepos; + + if (track == NULL) + track = "default"; + + current_buf = current_buf->next; + fail_unless (g_list_length (current_buf)); + encoded_clip = g_strdup_printf (CLIP_TEMPLATE_ENCODED, name, track); + check_output_buffer_is_equal (name, encoded_clip, 1); + g_free (encoded_clip); + buffer = GST_BUFFER (current_buf->data); + granulepos = GST_BUFFER_OFFSET_END (GST_BUFFER (buffer)); + keyindex = granulepos >> granuleshift; + keyoffset = granulepos - (keyindex << granuleshift); + fail_unless_equals_uint64 (keyindex * granulerate, prev); + fail_unless_equals_uint64 ((keyindex + keyoffset) * granulerate, start); +} + +static void +push_end () +{ + push_data ("end", END_TAG, strlen (END_TAG), GST_FLOW_OK); +} + +static void +check_end () +{ + /* should output the EOS page */ + current_buf = current_buf->next; + fail_unless_equals_int (g_list_length (current_buf), 1); + check_output_buffer_is_equal ("cmml-eos-buffer", NULL, 1); +} + +GST_START_TEST (test_enc) +{ + GstElement *cmmlenc; + + cmmlenc = setup_cmmlenc (); + + check_headers (); + + push_clip ("clip-1", "default", "1.234", NULL, GST_FLOW_OK); + check_clip ("clip-1", "default", 1234 * granulerate, 0); + + push_clip ("clip-2", NULL, "5.678", NULL, GST_FLOW_OK); + check_clip ("clip-2", "default", 5678 * granulerate, 1234 * granulerate); + + push_clip ("clip-3", "othertrack", "9.123", NULL, GST_FLOW_OK); + check_clip ("clip-3", "othertrack", 9123 * granulerate, 0); + + push_end (); + check_end (); + + cleanup_cmmlenc (cmmlenc); +} + +GST_END_TEST; + +GST_START_TEST (test_bad_start_time) +{ + GstElement *cmmlenc; + + cmmlenc = setup_cmmlenc (); + + check_headers (); + + push_clip ("clip-1", "default", "1.234", NULL, GST_FLOW_OK); + check_clip ("clip-1", "default", 1234 * granulerate, 0); + + push_clip ("clip-bad", "default", "1.1000", NULL, GST_FLOW_ERROR); + + push_clip ("clip-2", NULL, "5.678", NULL, GST_FLOW_OK); + check_clip ("clip-2", "default", 5678 * granulerate, 1234 * granulerate); + + push_clip ("clip-3", "othertrack", "9.123", NULL, GST_FLOW_OK); + check_clip ("clip-3", "othertrack", 9123 * granulerate, 0); + + push_end (); + check_end (); + + cleanup_cmmlenc (cmmlenc); +} +GST_END_TEST static Suite * +cmmlenc_suite () +{ + Suite *s = suite_create ("cmmlenc"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_enc); + tcase_add_test (tc_chain, test_bad_start_time); + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = cmmlenc_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; +} diff --git a/tests/check/elements/skeldec.c b/tests/check/elements/skeldec.c new file mode 100644 index 00000000..04d6dd3b --- /dev/null +++ b/tests/check/elements/skeldec.c @@ -0,0 +1,258 @@ +/* + * skeldec.c - GStreamer annodex skeleton decoder test suite + * Copyright (C) 2005 Alessandro Decina + * + * Authors: + * Alessandro Decina <alessandro@nnva.org> + * + * 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. + */ + +#include <gst/check/gstcheck.h> + +GList *buffers; + +GstPad *srcpad, *sinkpad; + +#define SKELETON_CAPS "application/x-ogg-skeleton" + +#define SKELETON_FISHEAD \ + "fishead\0"\ + "\x03\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + +#define SKELETON_FISHEAD_SIZE 64 + +#define SKELETON_FISBONE \ + "fisbone\0"\ + "\x2c\0\0\0"\ + "\x39\x30\0\0"\ + "\x39\x30\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0\0\0\0\0"\ + "\x39\x30\0\0"\ + "\x20"\ + "\0\0\0"\ + "Content-Type: application/ogg; UTF-8\r\n" + +#define SKELETON_FISBONE_SIZE 90 + +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (SKELETON_CAPS) + ); + +static GstElement * +setup_skeldec () +{ + GstElement *skeldec; + + GST_DEBUG ("setup_skeldec"); + skeldec = gst_check_setup_element ("skeldec"); + srcpad = gst_check_setup_src_pad (skeldec, &srctemplate, NULL); + sinkpad = gst_check_setup_sink_pad (skeldec, &sinktemplate, NULL); + + return skeldec; +} + +static void +cleanup_skeldec (GstElement * skeldec) +{ + GST_DEBUG ("cleanup_skeldec"); + + gst_check_teardown_src_pad (skeldec); + gst_check_teardown_sink_pad (skeldec); + gst_check_teardown_element (skeldec); +} + +static void +skel_buffer_unref (void *buf, void *user_data) +{ + GstBuffer *buffer = GST_BUFFER (buf); + + ASSERT_OBJECT_REFCOUNT (buffer, "skel-buffer", 1); + gst_buffer_unref (buffer); +} + +static GstBuffer * +skel_buffer_new (gchar * buffer_data, guint size) +{ + GstBuffer *buffer; + GstCaps *caps; + + buffer = gst_buffer_new_and_alloc (size); + memcpy (GST_BUFFER_DATA (buffer), buffer_data, size); + caps = gst_caps_from_string (SKELETON_CAPS); + gst_buffer_set_caps (buffer, caps); + gst_caps_unref (caps); + + return buffer; +} + +GST_START_TEST (test_dec) +{ + GstElement *skeldec; + GstBus *bus; + GstBuffer *inbuffer; + GstMessage *message; + GstTagList *tags; + const GValue *tag_val, *val; + GObject *tag; + gint major, minor; + gint64 prestime_n, prestime_d; + gint64 basetime_n, basetime_d; + guint serial_number; + gint64 granule_rate_n, granule_rate_d; + gint64 granule_start; + guint64 preroll; + guint granule_shift; + GValueArray *headers; + gchar *content_type; + gchar *encoding; + + skeldec = setup_skeldec (); + + bus = gst_bus_new (); + gst_element_set_bus (skeldec, bus); + + fail_unless (gst_element_set_state (skeldec, + GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, + "could not set to playing"); + + /* test the fishead */ + inbuffer = skel_buffer_new (SKELETON_FISHEAD, SKELETON_FISHEAD_SIZE); + fail_unless_equals_int (gst_pad_push (srcpad, inbuffer), GST_FLOW_OK); + + message = gst_bus_poll (bus, GST_MESSAGE_TAG, -1); + fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (skeldec)); + + gst_message_parse_tag (message, &tags); + fail_unless (tags != NULL); + fail_unless_equals_int (gst_tag_list_get_tag_size (tags, + GST_TAG_SKELETON_FISHEAD), 1); + + tag_val = gst_tag_list_get_value_index (tags, GST_TAG_SKELETON_FISHEAD, 0); + fail_unless (tag_val != NULL); + + tag = g_value_get_object (tag_val); + fail_unless (tag != NULL); + + g_object_get (tag, + "version-major", &major, "version-minor", &minor, + "presentation-time-numerator", &prestime_n, + "presentation-time-denominator", &prestime_d, + "base-time-numerator", &basetime_n, + "base-time-denominator", &basetime_d, NULL); + + fail_unless_equals_int (major, 3); + fail_unless_equals_int (minor, 0); + fail_unless_equals_int (prestime_n, 12345); + fail_unless_equals_int (prestime_d, 12345); + fail_unless_equals_int (basetime_n, 12345); + fail_unless_equals_int (basetime_d, 12345); + + gst_tag_list_free (tags); + gst_message_unref (message); + + /* test the fisbone */ + inbuffer = skel_buffer_new (SKELETON_FISBONE, SKELETON_FISBONE_SIZE); + fail_unless_equals_int (gst_pad_push (srcpad, inbuffer), GST_FLOW_OK); + + message = gst_bus_poll (bus, GST_MESSAGE_TAG, -1); + fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (skeldec)); + + gst_message_parse_tag (message, &tags); + fail_unless (tags != NULL); + fail_unless_equals_int (gst_tag_list_get_tag_size (tags, + GST_TAG_SKELETON_FISBONE), 1); + + tag_val = gst_tag_list_get_value_index (tags, GST_TAG_SKELETON_FISBONE, 0); + fail_unless (tag_val != NULL); + + tag = g_value_get_object (tag_val); + fail_unless (tag != NULL); + + g_object_get (tag, "serial-number", &serial_number, + "granule-rate-numerator", &granule_rate_n, + "granule-rate-denominator", &granule_rate_d, + "granule-start", &granule_start, + "granule-shift", &granule_shift, + "preroll", &preroll, + "headers", &headers, + "content-type", &content_type, "encoding", &encoding, NULL); + + fail_unless_equals_int (serial_number, 12345); + fail_unless_equals_int (granule_rate_n, 12345); + fail_unless_equals_int (granule_rate_d, 12345); + fail_unless_equals_int (granule_start, 12345); + fail_unless_equals_int (preroll, 12345); + fail_unless_equals_int (granule_shift, 32); + fail_unless_equals_int (headers->n_values, 2); + fail_unless_equals_string (content_type, "application/ogg"); + fail_unless_equals_string (encoding, "UTF-8"); + + g_value_array_free (headers); + g_free (content_type); + g_free (encoding); + gst_tag_list_free (tags); + gst_message_unref (message); + gst_bus_set_flushing (bus, TRUE); + gst_object_unref (bus); + g_list_foreach (buffers, skel_buffer_unref, NULL); + cleanup_skeldec (skeldec); +} + +GST_END_TEST; + +static Suite * +skeldec_suite () +{ + Suite *s = suite_create ("skeldec"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_dec); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = skeldec_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; +} |