diff options
Diffstat (limited to 'tests/check/pipelines/oggmux.c')
-rw-r--r-- | tests/check/pipelines/oggmux.c | 430 |
1 files changed, 0 insertions, 430 deletions
diff --git a/tests/check/pipelines/oggmux.c b/tests/check/pipelines/oggmux.c deleted file mode 100644 index 16bb3f20..00000000 --- a/tests/check/pipelines/oggmux.c +++ /dev/null @@ -1,430 +0,0 @@ -/* GStreamer - * - * unit tests for oggmux - * - * Copyright (C) 2006 James Livingston <doclivingston at gmail.com> - * - * 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 <string.h> - -#include <gst/check/gstcheck.h> -#include <ogg/ogg.h> - - -typedef enum -{ - CODEC_UNKNOWN, - CODEC_VORBIS, - CODEC_THEORA, - CODEC_SPEEX, -} ChainCodec; - -typedef struct -{ - gboolean eos; - gulong serialno; - gint64 last_granule; - ChainCodec codec; -} ChainState; - -static ogg_sync_state oggsync; -static GHashTable *eos_chain_states; -static gulong probe_id; - - -static ChainCodec -get_page_codec (ogg_page * page) -{ - ChainCodec codec = CODEC_UNKNOWN; - ogg_stream_state state; - ogg_packet packet; - - ogg_stream_init (&state, ogg_page_serialno (page)); - if (ogg_stream_pagein (&state, page) == 0) { - if (ogg_stream_packetpeek (&state, &packet) > 0) { - if (strncmp ((char *) &packet.packet[1], "vorbis", - strlen ("vorbis")) == 0) - codec = CODEC_VORBIS; - else if (strncmp ((char *) &packet.packet[1], "theora", - strlen ("theora")) == 0) - codec = CODEC_THEORA; - else if (strncmp ((char *) &packet.packet[0], "Speex ", - strlen ("Speex ")) == 0) - codec = CODEC_SPEEX; - } - } - ogg_stream_clear (&state); - - return codec; -} - -static gboolean -check_chain_final_state (gpointer key, ChainState * state, gpointer data) -{ - fail_unless (state->eos, "missing EOS flag on chain %u", state->serialno); - - /* return TRUE to empty the chain table */ - return TRUE; -} - -static void -fail_if_audio (gpointer key, ChainState * state, gpointer data) -{ - fail_if (state->codec == CODEC_VORBIS, - "vorbis BOS occurred before theora BOS"); - fail_if (state->codec == CODEC_SPEEX, "speex BOS occurred before theora BOS"); -} - -static ChainState * -validate_ogg_page (ogg_page * page) -{ - gulong serialno; - gint64 granule; - ChainState *state; - - serialno = ogg_page_serialno (page); - granule = ogg_page_granulepos (page); - state = g_hash_table_lookup (eos_chain_states, GINT_TO_POINTER (serialno)); - - fail_if (ogg_page_packets (page) == 0 && granule != -1, - "Must have granulepos -1 when page has no packets, has %" G_GINT64_FORMAT, - granule); - - if (ogg_page_bos (page)) { - fail_unless (state == NULL, "Extraneous BOS flag on chain %u", serialno); - - state = g_new0 (ChainState, 1); - g_hash_table_insert (eos_chain_states, GINT_TO_POINTER (serialno), state); - state->serialno = serialno; - state->last_granule = granule; - state->codec = get_page_codec (page); - - /* check for things like BOS ordering, etc */ - switch (state->codec) { - case CODEC_THEORA: - /* check we have no vorbis/speex chains yet */ - g_hash_table_foreach (eos_chain_states, (GHFunc) fail_if_audio, NULL); - break; - case CODEC_VORBIS: - case CODEC_SPEEX: - /* no checks (yet) */ - break; - case CODEC_UNKNOWN: - default: - break; - } - } else if (ogg_page_eos (page)) { - fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno); - state->eos = TRUE; - } else { - fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno); - fail_unless (!state->eos, "Data after EOS flag on chain %u", serialno); - } - - if (granule != -1) { - fail_unless (granule >= state->last_granule, - "Granulepos out-of-order for chain %u: old=%" G_GINT64_FORMAT ", new=" - G_GINT64_FORMAT, serialno, state->last_granule, granule); - state->last_granule = granule; - } - - return state; -} - -static void -is_video (gpointer key, ChainState * state, gpointer data) -{ - if (state->codec == CODEC_THEORA) - *((gboolean *) data) = TRUE; -} - - -static gboolean -eos_buffer_probe (GstPad * pad, GstBuffer * buffer, gpointer unused) -{ - gint ret; - gint size; - guint8 *data; - gchar *oggbuffer; - ChainState *state = NULL; - gboolean has_video = FALSE; - - size = GST_BUFFER_SIZE (buffer); - data = GST_BUFFER_DATA (buffer); - - oggbuffer = ogg_sync_buffer (&oggsync, size); - memcpy (oggbuffer, data, size); - ogg_sync_wrote (&oggsync, size); - - do { - ogg_page page; - - ret = ogg_sync_pageout (&oggsync, &page); - if (ret > 0) - state = validate_ogg_page (&page); - } - while (ret != 0); - - if (state) { - /* Now, we can do buffer-level checks... - * If we have video somewhere, then we should have DELTA_UNIT set on all - * non-header (not IN_CAPS), non-video buffers - */ - g_hash_table_foreach (eos_chain_states, (GHFunc) is_video, &has_video); - if (has_video && state->codec != CODEC_THEORA) { - if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_IN_CAPS)) - fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, - GST_BUFFER_FLAG_DELTA_UNIT), - "Non-video buffer doesn't have DELTA_UNIT in stream with video"); - } - } - - return TRUE; -} - -static void -start_pipeline (GstElement * bin, GstPad * pad) -{ - GstStateChangeReturn ret; - - ogg_sync_init (&oggsync); - - eos_chain_states = - g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - probe_id = - gst_pad_add_buffer_probe (pad, G_CALLBACK (eos_buffer_probe), NULL); - - ret = gst_element_set_state (bin, GST_STATE_PLAYING); - fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not start test pipeline"); - if (ret == GST_STATE_CHANGE_ASYNC) { - ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE); - fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not start test pipeline"); - } -} - -static void -stop_pipeline (GstElement * bin, GstPad * pad) -{ - GstStateChangeReturn ret; - - ret = gst_element_set_state (bin, GST_STATE_NULL); - fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not stop test pipeline"); - if (ret == GST_STATE_CHANGE_ASYNC) { - ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE); - fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not stop test pipeline"); - } - - gst_pad_remove_buffer_probe (pad, (guint) probe_id); - ogg_sync_clear (&oggsync); - - /* check end conditions, such as EOS flags */ - g_hash_table_foreach_remove (eos_chain_states, - (GHRFunc) check_chain_final_state, NULL); -} - -static gboolean -eos_watch (GstBus * bus, GstMessage * message, GMainLoop * loop) -{ - if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS) { - g_main_loop_quit (loop); - } - return TRUE; -} - -static void -test_pipeline (const char *pipeline) -{ - GstElement *bin, *sink; - GstPad *pad, *sinkpad; - GstBus *bus; - GError *error = NULL; - GMainLoop *loop; - GstPadLinkReturn linkret; - - bin = gst_parse_launch (pipeline, &error); - fail_unless (bin != NULL, "Error parsing pipeline: %s", - error ? error->message : "(invalid error)"); - pad = gst_bin_find_unlinked_pad (GST_BIN (bin), GST_PAD_SRC); - fail_unless (pad != NULL, "Could not locate free src pad"); - - /* connect the fake sink */ - sink = gst_element_factory_make ("fakesink", "fake_sink"); - fail_unless (sink != NULL, "Could create fakesink"); - fail_unless (gst_bin_add (GST_BIN (bin), sink), "Could not insert fakesink"); - sinkpad = gst_element_get_static_pad (sink, "sink"); - fail_unless (sinkpad != NULL, "Could not get fakesink src pad"); - - linkret = gst_pad_link (pad, sinkpad); - fail_unless (GST_PAD_LINK_SUCCESSFUL (linkret), - "Could not link to fake sink"); - gst_object_unref (sinkpad); - - /* run until we receive EOS */ - loop = g_main_loop_new (NULL, FALSE); - bus = gst_element_get_bus (bin); - gst_bus_add_watch (bus, (GstBusFunc) eos_watch, loop); - gst_object_unref (bus); - - start_pipeline (bin, pad); - g_main_loop_run (loop); - - /* we're EOS now; make sure oggmux out caps have stream headers on them */ - { - GstStructure *s; - GstCaps *muxcaps; - - muxcaps = gst_pad_get_negotiated_caps (sinkpad); - fail_unless (muxcaps != NULL); - s = gst_caps_get_structure (muxcaps, 0); - fail_unless (gst_structure_has_name (s, "application/ogg")); - fail_unless (gst_structure_has_field (s, "streamheader")); - fail_unless (gst_structure_has_field_typed (s, "streamheader", - GST_TYPE_ARRAY)); - gst_caps_unref (muxcaps); - } - - stop_pipeline (bin, pad); - - /* clean up */ - g_main_loop_unref (loop); - gst_object_unref (pad); - gst_object_unref (bin); -} - -#ifdef HAVE_VORBIS -GST_START_TEST (test_vorbis) -{ - test_pipeline - ("audiotestsrc num-buffers=5 ! audioconvert ! vorbisenc ! oggmux"); -} - -GST_END_TEST; - -GST_START_TEST (test_vorbis_oggmux_unlinked) -{ - GstElement *pipe; - GstMessage *msg; - - pipe = gst_parse_launch ("audiotestsrc ! vorbisenc ! oggmux", NULL); - if (pipe == NULL) { - g_printerr ("Skipping test 'test_vorbis_oggmux_unlinked'"); - return; - } - /* no sink, no async state change */ - fail_unless_equals_int (gst_element_set_state (pipe, GST_STATE_PAUSED), - GST_STATE_CHANGE_SUCCESS); - /* we expect an error (without any criticals/warnings) */ - msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe), -1, - GST_MESSAGE_ERROR); - gst_message_unref (msg); - fail_unless_equals_int (gst_element_set_state (pipe, GST_STATE_NULL), - GST_STATE_CHANGE_SUCCESS); - gst_object_unref (pipe); -} - -GST_END_TEST; -#endif - -#ifdef HAVE_THEORA -GST_START_TEST (test_theora) -{ - test_pipeline - ("videotestsrc num-buffers=5 ! ffmpegcolorspace ! theoraenc ! oggmux"); -} - -GST_END_TEST; -#endif - -#if (defined (HAVE_THEORA) && defined (HAVE_VORBIS)) -GST_START_TEST (test_theora_vorbis) -{ - test_pipeline - ("videotestsrc num-buffers=10 ! ffmpegcolorspace ! theoraenc ! queue ! oggmux name=mux " - "audiotestsrc num-buffers=2 ! audioconvert ! vorbisenc ! queue ! mux."); -} - -GST_END_TEST; - -GST_START_TEST (test_vorbis_theora) -{ - test_pipeline - ("videotestsrc num-buffers=2 ! ffmpegcolorspace ! theoraenc ! queue ! oggmux name=mux " - "audiotestsrc num-buffers=10 ! audioconvert ! vorbisenc ! queue ! mux."); -} - -GST_END_TEST; -#endif - -GST_START_TEST (test_simple_cleanup) -{ - GstElement *oggmux; - - oggmux = gst_element_factory_make ("oggmux", NULL); - gst_object_unref (oggmux); -} - -GST_END_TEST; - -GST_START_TEST (test_request_pad_cleanup) -{ - GstElement *oggmux; - GstPad *pad; - - oggmux = gst_element_factory_make ("oggmux", NULL); - pad = gst_element_get_request_pad (oggmux, "sink_%d"); - fail_unless (pad != NULL); - gst_object_unref (pad); - pad = gst_element_get_request_pad (oggmux, "sink_%d"); - fail_unless (pad != NULL); - gst_object_unref (pad); - gst_object_unref (oggmux); -} - -GST_END_TEST; - -static Suite * -oggmux_suite (void) -{ - Suite *s = suite_create ("oggmux"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); -#ifdef HAVE_VORBIS - tcase_add_test (tc_chain, test_vorbis); - tcase_add_test (tc_chain, test_vorbis_oggmux_unlinked); -#endif - -#ifdef HAVE_THEORA - tcase_add_test (tc_chain, test_theora); -#endif - -#if (defined (HAVE_THEORA) && defined (HAVE_VORBIS)) - tcase_add_test (tc_chain, test_vorbis_theora); - tcase_add_test (tc_chain, test_theora_vorbis); -#endif - - tcase_add_test (tc_chain, test_simple_cleanup); - tcase_add_test (tc_chain, test_request_pad_cleanup); - return s; -} - -GST_CHECK_MAIN (oggmux); |