void test_refcounts() { GstNetTimeProvider *ntp; GstClock *clock; xmlfile = "test_refcounts"; std_log(LOG_FILENAME_LINE, "Test Started test_refcounts"); clock = gst_system_clock_obtain (); fail_unless (clock != NULL, "failed to get system clock"); /* one for gstreamer, one for us */ ASSERT_OBJECT_REFCOUNT (clock, "system clock", 2); ntp = gst_net_time_provider_new (clock, NULL, 0); fail_unless (ntp != NULL, "failed to create net time provider"); /* one for ntp, one for gstreamer, one for us */ ASSERT_OBJECT_REFCOUNT (clock, "system clock", 3); /* one for us */ ASSERT_OBJECT_REFCOUNT (ntp, "net time provider", 1); gst_object_unref (ntp); ASSERT_OBJECT_REFCOUNT (clock, "net time provider", 2); gst_object_unref (clock); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* Create and link input pad: input_pad ! selector:sink%d */ static GstPad * setup_input_pad (GstElement * element) { GstPad *sinkpad = NULL, *input_pad = NULL; /* create input_pad */ input_pad = gst_pad_new_from_static_template (&srctemplate, "src"); fail_if (input_pad == NULL, "Could not create a input_pad"); /* request sink pad */ sinkpad = gst_element_get_request_pad (element, "sink_%u"); fail_if (sinkpad == NULL, "Could not get sink pad from %s", GST_ELEMENT_NAME (element)); /* link pads and activate */ fail_unless (gst_pad_link (input_pad, sinkpad) == GST_PAD_LINK_OK, "Could not link input_pad and %s sink", GST_ELEMENT_NAME (element)); gst_pad_set_active (input_pad, TRUE); GST_DEBUG_OBJECT (input_pad, "set up %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT, input_pad, sinkpad); gst_object_unref (sinkpad); ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 1); return input_pad; }
/* Clean up output/input pad and respective selector request pad */ static void cleanup_pad (GstPad * pad, GstElement * element) { GstPad *selpad = NULL; guint probe_id = 0; fail_if (pad == NULL, "pad doesn't exist"); /* remove probe if necessary */ probe_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "probe_id")); if (probe_id) gst_pad_remove_probe (pad, probe_id); /* unlink */ selpad = gst_pad_get_peer (pad); if (GST_PAD_DIRECTION (selpad) == GST_PAD_SRC) { gst_pad_unlink (selpad, pad); } else { gst_pad_unlink (pad, selpad); } GST_DEBUG_OBJECT (pad, "clean up %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT, selpad, pad); /* cleanup the pad */ gst_pad_set_active (pad, FALSE); ASSERT_OBJECT_REFCOUNT (pad, "pad", 1); gst_object_unref (pad); /* cleanup selector pad, reffed by this function (_get_peer) and creator */ gst_element_release_request_pad (element, selpad); gst_object_unref (selpad); }
static void _test_flow_aggregation (GstFlowReturn flow, GstFlowReturn flow1, GstFlowReturn flow2, GstFlowReturn demux_flow, gboolean should_fail) { GstPad *srcpad; GstValidateReport *report; GstValidatePadMonitor *pmonitor, *pmonitor1, *pmonitor2; GstElement *demuxer = fake_demuxer_new (); GstBin *pipeline = GST_BIN (gst_pipeline_new ("validate-pipeline")); GList *reports; GstValidateRunner *runner; GstValidateMonitor *monitor; fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (pipeline), runner, NULL); gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor)); gst_bin_add (pipeline, demuxer); fake_demuxer_prepare_pads (pipeline, demuxer, runner); srcpad = gst_pad_new ("srcpad1", GST_PAD_SRC); gst_pad_link (srcpad, demuxer->sinkpads->data); fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE)); gst_check_setup_events_with_stream_id (srcpad, demuxer, NULL, GST_FORMAT_TIME, "the-stream"); pmonitor = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->data)); pmonitor1 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->data)); pmonitor2 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->next->data)); pmonitor->last_flow_return = flow; pmonitor1->last_flow_return = flow1; pmonitor2->last_flow_return = flow2; FAKE_DEMUXER (demuxer)->return_value = demux_flow; fail_unless_equals_int (gst_pad_push (srcpad, gst_buffer_new ()), demux_flow); reports = gst_validate_runner_get_reports (runner); if (should_fail) { assert_equals_int (g_list_length (reports), 1); report = reports->data; fail_unless_equals_int (report->level, GST_VALIDATE_REPORT_LEVEL_CRITICAL); fail_unless_equals_int (report->issue->issue_id, WRONG_FLOW_RETURN); } else { assert_equals_int (g_list_length (reports), 0); } g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref); clean_bus (GST_ELEMENT (pipeline)); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); ASSERT_OBJECT_REFCOUNT (pipeline, "ours", 1); check_destroyed (pipeline, demuxer, NULL); check_destroyed (monitor, pmonitor, NULL); }
static void test_suburi_error_wrongproto (void) { GstElement *playbin, *fakesink; fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY, gst_red_video_src_get_type ())); playbin = gst_element_factory_make ("playbin", "playbin"); fail_unless (playbin != NULL, "Failed to create playbin element"); fakesink = gst_element_factory_make ("fakesink", "fakesink"); fail_unless (fakesink != NULL, "Failed to create fakesink element"); ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1); g_object_set (playbin, "video-sink", fakesink, NULL); /* wrong protocol for suburi: playbin should just ignore the suburi and * preroll normally */ g_object_set (playbin, "uri", "redvideo://", NULL); g_object_set (playbin, "suburi", "nosuchproto://foo.bar:80", NULL); fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY), GST_STATE_CHANGE_SUCCESS); fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED), GST_STATE_CHANGE_ASYNC); fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1), GST_STATE_CHANGE_SUCCESS); gst_element_set_state (playbin, GST_STATE_NULL); gst_object_unref (playbin); }
static void test_suburi_error_unknowntype (void) { GstElement *playbin, *fakesink; fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY, gst_red_video_src_get_type ())); playbin = gst_element_factory_make ("playbin", "playbin"); fail_unless (playbin != NULL, "Failed to create playbin element"); fakesink = gst_element_factory_make ("fakesink", "fakesink"); fail_unless (fakesink != NULL, "Failed to create fakesink element"); ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1); g_object_set (playbin, "video-sink", fakesink, NULL); /* suburi file format unknown: playbin should just ignore the suburi and * preroll normally (if /dev/zero does not exist, this test should behave * the same as test_suburi_error_invalidfile() */ g_object_set (playbin, "uri", "redvideo://", NULL); g_object_set (playbin, "suburi", "file:///dev/zero", NULL); fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY), GST_STATE_CHANGE_SUCCESS); fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED), GST_STATE_CHANGE_ASYNC); fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1), GST_STATE_CHANGE_SUCCESS); gst_element_set_state (playbin, GST_STATE_NULL); gst_object_unref (playbin); }
/* Create and link output pad: selector:src%d ! output_pad */ GstPad * setup_output_pad (GstElement * element) { GstPad *srcpad = NULL, *output_pad = NULL; gulong probe_id = 0; /* create output_pad */ output_pad = gst_pad_new_from_static_template (&sinktemplate, "sink"); fail_if (output_pad == NULL, "Could not create a output_pad"); /* add probe */ probe_id = gst_pad_add_data_probe (output_pad, G_CALLBACK (probe_cb), NULL); g_object_set_data (G_OBJECT (output_pad), "probe_id", GINT_TO_POINTER (probe_id)); /* request src pad */ srcpad = gst_element_get_request_pad (element, "src%d"); fail_if (srcpad == NULL, "Could not get source pad from %s", GST_ELEMENT_NAME (element)); /* link pads and activate */ fail_unless (gst_pad_link (srcpad, output_pad) == GST_PAD_LINK_OK, "Could not link %s source and output pad", GST_ELEMENT_NAME (element)); gst_pad_set_active (output_pad, TRUE); GST_DEBUG_OBJECT (output_pad, "set up %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT, srcpad, output_pad); gst_object_unref (srcpad); ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 1); return output_pad; }
void test_registry() { GList *g; GstRegistry *registry; //xmlfile = "test_registry"; std_log(LOG_FILENAME_LINE, "Test Started test_registry"); registry = gst_registry_get_default (); for (g = registry->plugins; g; g = g->next) { GstPlugin *plugin = GST_PLUGIN (g->data); ASSERT_OBJECT_REFCOUNT (plugin, "plugin in registry", 1); GST_DEBUG ("refcount %d %s", GST_OBJECT_REFCOUNT_VALUE (plugin), plugin->desc.name); } for (g = registry->features; g; g = g->next) { GstPluginFeature *feature = GST_PLUGIN_FEATURE (g->data); fail_if (GST_OBJECT_REFCOUNT_VALUE (feature) != 1, "Feature in registry should have refcount of 1"); GST_DEBUG ("refcount %d %s", GST_OBJECT_REFCOUNT_VALUE (feature), feature->name); } std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_find_plugin() { GstPlugin *plugin; //xmlfile = "test_find_plugin"; std_log(LOG_FILENAME_LINE, "Test Started test_find_plugin"); plugin = gst_registry_find_plugin (gst_registry_get_default (), "coreelements"); fail_if (plugin == NULL, "Failed to find coreelements plugin"); ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 2); fail_unless_equals_string (plugin->desc.version, VERSION); fail_unless_equals_string (plugin->desc.license, "LGPL"); fail_unless_equals_string (plugin->desc.source, "gstreamer"); fail_unless_equals_string (plugin->desc.package, GST_PACKAGE_NAME); fail_unless_equals_string (plugin->desc.origin, GST_PACKAGE_ORIGIN); gst_object_unref (plugin); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void asset_created_cb (GObject * source, GAsyncResult * res, gpointer udata) { GList *tracks, *tmp; GESAsset *asset; GESLayer *layer; GESUriClip *tlfs; GError *error = NULL; asset = ges_asset_request_finish (res, &error); ASSERT_OBJECT_REFCOUNT (asset, "1 for us + for the cache + 1 taken " "by g_simple_async_result_complete_in_idle", 3); fail_unless (error == NULL); fail_if (asset == NULL); fail_if (g_strcmp0 (ges_asset_get_id (asset), av_uri)); layer = GES_LAYER (g_async_result_get_user_data (res)); tlfs = GES_URI_CLIP (ges_layer_add_asset (layer, asset, 0, 0, GST_CLOCK_TIME_NONE, GES_TRACK_TYPE_UNKNOWN)); fail_unless (GES_IS_URI_CLIP (tlfs)); fail_if (g_strcmp0 (ges_uri_clip_get_uri (tlfs), av_uri)); assert_equals_uint64 (_DURATION (tlfs), GST_SECOND); fail_unless (ges_clip_get_supported_formats (GES_CLIP (tlfs)) & GES_TRACK_TYPE_VIDEO); fail_unless (ges_clip_get_supported_formats (GES_CLIP (tlfs)) & GES_TRACK_TYPE_AUDIO); tracks = ges_timeline_get_tracks (ges_layer_get_timeline (layer)); for (tmp = tracks; tmp; tmp = tmp->next) { GList *trackelements = ges_track_get_elements (GES_TRACK (tmp->data)); assert_equals_int (g_list_length (trackelements), 1); fail_unless (GES_IS_VIDEO_URI_SOURCE (trackelements->data) || GES_IS_AUDIO_URI_SOURCE (trackelements->data)); g_list_free_full (trackelements, gst_object_unref); } g_list_free_full (tracks, gst_object_unref); gst_object_unref (asset); g_main_loop_quit (mainloop); }
static void check_output_buffer_is_equal (const gchar * name, const gchar * data, gint refcount) { GstBuffer *buffer; if (current_buf == NULL) current_buf = buffers; else current_buf = g_list_next (current_buf); fail_unless (current_buf != NULL); 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 test_one_after_other_full (gboolean async) { GstElement *pipeline; GstElement *comp, *sink, *source1, *source2; CollectStructure *collect; GstBus *bus; GstMessage *message; gboolean carry_on = TRUE; guint64 start, stop; gint64 duration; GstPad *sinkpad; pipeline = gst_pipeline_new ("test_pipeline"); comp = gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); fail_if (comp == NULL); /* Source 1 Start : 0s Duration : 1s Media start : 5s Media Duartion : 1s Priority : 1 */ source1 = videotest_gnl_src_full ("source1", 0, 1 * GST_SECOND, 5 * GST_SECOND, 1 * GST_SECOND, 3, 1); fail_if (source1 == NULL); check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND); /* Source 2 Start : 1s Duration : 1s Media start : 2s Media Duration : 1s Priority : 1 */ source2 = videotest_gnl_src_full ("source2", 1 * GST_SECOND, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND, 2, 1); fail_if (source2 == NULL); check_start_stop_duration (source2, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); /* Add one source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 1 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Second source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source2); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); /* Remove first source */ gst_object_ref (source1); DISABLE_ASYNC_UPDATE; gst_bin_remove (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Re-add first source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); gst_object_unref (source1); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); sink = gst_element_factory_make_or_warn ("fakesink", "sink"); fail_if (sink == NULL); gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL); /* Shared data */ collect = g_new0 (CollectStructure, 1); collect->comp = comp; collect->sink = sink; /* Expected segments */ collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND)); g_signal_connect (G_OBJECT (comp), "pad-added", G_CALLBACK (composition_pad_added_cb), collect); sinkpad = gst_element_get_pad (sink, "sink"); gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect); gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe), collect); bus = gst_element_get_bus (GST_ELEMENT (pipeline)); GST_DEBUG ("Setting pipeline to PLAYING"); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); GST_DEBUG ("Let's poll the bus"); while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ GST_WARNING ("Got an EOS"); carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* We shouldn't see any segement messages, since we didn't do a segment seek */ GST_WARNING ("Saw a Segment start/stop"); fail_if (TRUE); break; case GST_MESSAGE_ERROR: GST_WARNING ("Saw an ERROR"); fail_if (TRUE); default: break; } gst_mini_object_unref (GST_MINI_OBJECT (message)); } } GST_DEBUG ("Setting pipeline to NULL"); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); fail_if (collect->expected_segments != NULL); GST_DEBUG ("Resetted pipeline to READY"); /* Expected segments */ collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND)); collect->gotsegment = FALSE; GST_DEBUG ("Setting pipeline to PLAYING again"); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); carry_on = TRUE; GST_DEBUG ("Let's poll the bus AGAIN"); while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* We shouldn't see any segement messages, since we didn't do a segment seek */ GST_WARNING ("Saw a Segment start/stop"); fail_if (TRUE); break; case GST_MESSAGE_ERROR: GST_ERROR ("Saw an ERROR"); fail_if (TRUE); default: break; } gst_mini_object_unref (GST_MINI_OBJECT (message)); } else { GST_DEBUG ("bus_poll responded, but there wasn't any message..."); } } fail_if (collect->expected_segments != NULL); gst_object_unref (GST_OBJECT (sinkpad)); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE); ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2); gst_object_unref (pipeline); ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2); gst_object_unref (bus); g_free (collect); }
static void test_time_duration_full (gboolean async) { guint64 start, stop; gint64 duration; GstElement *comp, *source1, *source2; comp = gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); /* Source 1 Start : 0s Duration : 1s Priority : 1 */ source1 = videotest_gnl_src ("source1", 0, 1 * GST_SECOND, 3, 1); fail_if (source1 == NULL); check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND); /* Source 2 Start : 1s Duration : 1s Priority : 1 */ source2 = videotest_gnl_src ("source2", 1 * GST_SECOND, 1 * GST_SECOND, 2, 1); fail_if (source2 == NULL); check_start_stop_duration (source2, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); /* Add one source */ ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 1 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Second source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source2); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); /* Remove first source */ gst_object_ref (source1); DISABLE_ASYNC_UPDATE; gst_bin_remove (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Re-add first source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); gst_object_unref (source1); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); gst_object_unref (comp); }
static void _check_media_info (GstSegment * segment, BufferDesc * bufs) { GList *reports; GstEvent *segev; GstBuffer *buffer; GstElement *decoder; GstPad *srcpad, *sinkpad; GstValidateReport *report; GstValidateMonitor *monitor; GstValidateRunner *runner; GstMediaDescriptor *mdesc; GError *err = NULL; gint i, num_issues = 0; fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); mdesc = (GstMediaDescriptor *) gst_media_descriptor_parser_new_from_xml (runner, media_info, &err); decoder = fake_decoder_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (decoder), runner, NULL); gst_validate_monitor_set_media_descriptor (monitor, mdesc); srcpad = gst_pad_new ("src", GST_PAD_SRC); sinkpad = decoder->sinkpads->data; ASSERT_OBJECT_REFCOUNT (sinkpad, "decoder ref", 1); fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE)); fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS); assert_equals_string (gst_pad_link_get_name (gst_pad_link (srcpad, sinkpad)), gst_pad_link_get_name (GST_PAD_LINK_OK)); gst_check_setup_events_with_stream_id (srcpad, decoder, gst_caps_from_string ("video/x-fake"), GST_FORMAT_TIME, "the-stream"); if (segment) { segev = gst_event_new_segment (segment); fail_unless (gst_pad_push_event (srcpad, segev)); } for (i = 0; bufs[i].content != NULL; i++) { BufferDesc *buf = &bufs[i]; buffer = _create_buffer (buf); assert_equals_string (gst_flow_get_name (gst_pad_push (srcpad, buffer)), gst_flow_get_name (GST_FLOW_OK)); reports = gst_validate_runner_get_reports (runner); num_issues += buf->num_issues; assert_equals_int (g_list_length (reports), num_issues); if (buf->num_issues) { GList *tmp = g_list_nth (reports, num_issues - buf->num_issues); while (tmp) { report = tmp->data; fail_unless_equals_int (report->level, GST_VALIDATE_REPORT_LEVEL_WARNING); fail_unless_equals_int (report->issue->issue_id, WRONG_BUFFER); tmp = tmp->next; } } } /* clean up */ fail_unless (gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, FALSE)); fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); gst_object_unref (srcpad); check_destroyed (decoder, sinkpad, NULL); check_destroyed (runner, NULL, NULL); }
/* * Create a demux element, run a test using the input data and check * the output data */ void gst_adaptive_demux_test_run (const gchar * element_name, const gchar * manifest_uri, const GstAdaptiveDemuxTestCallbacks * callbacks, gpointer user_data) { GstBus *bus; GstElement *demux; GstElement *manifest_source; gboolean ret; GstStateChangeReturn stateChange; GstAdaptiveDemuxTestEnginePrivate *priv; priv = g_slice_new0 (GstAdaptiveDemuxTestEnginePrivate); priv->engine.output_streams = g_ptr_array_new_with_free_func (adaptive_demux_engine_stream_state_finalize); g_mutex_init (&priv->engine.lock); priv->callbacks = callbacks; priv->user_data = user_data; priv->engine.loop = g_main_loop_new (NULL, TRUE); fail_unless (priv->engine.loop != NULL); GST_TEST_LOCK (priv); priv->engine.pipeline = gst_pipeline_new ("pipeline"); fail_unless (priv->engine.pipeline != NULL); GST_DEBUG ("created pipeline %" GST_PTR_FORMAT, priv->engine.pipeline); /* register a callback to listen for error messages */ bus = gst_pipeline_get_bus (GST_PIPELINE (priv->engine.pipeline)); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); g_signal_connect (bus, "message::error", G_CALLBACK (on_ErrorMessageOnBus), priv); manifest_source = gst_element_make_from_uri (GST_URI_SRC, manifest_uri, NULL, NULL); fail_unless (manifest_source != NULL); priv->engine.manifest_source = manifest_source; demux = gst_check_setup_element (element_name); fail_unless (demux != NULL); priv->engine.demux = demux; GST_DEBUG ("created demux %" GST_PTR_FORMAT, demux); g_signal_connect (demux, "element-added", G_CALLBACK (on_demuxElementAdded), priv); g_signal_connect (demux, "pad-added", G_CALLBACK (on_demuxNewPad), priv); g_signal_connect (demux, "pad-removed", G_CALLBACK (on_demuxPadRemoved), priv); gst_bin_add_many (GST_BIN (priv->engine.pipeline), manifest_source, demux, NULL); ASSERT_OBJECT_REFCOUNT (manifest_source, element_name, 1); ASSERT_OBJECT_REFCOUNT (demux, element_name, 1); ret = gst_element_link (manifest_source, demux); fail_unless_equals_int (ret, TRUE); priv->engine.clock = gst_system_clock_obtain (); if (GST_IS_TEST_CLOCK (priv->engine.clock)) { /* * live tests will want to manipulate the clock, so they will register a * gst_test_clock as the system clock. * The on demand tests do not care about the clock, so they will let the * system clock to the default one. * If a gst_test_clock was installed as system clock, we register a * periodic callback to update its value. */ priv->clock_update_id = g_timeout_add (100, gst_adaptive_demux_update_test_clock, priv); } /* call a test callback before we start the pipeline */ if (callbacks->pre_test) (*callbacks->pre_test) (&priv->engine, priv->user_data); GST_TEST_UNLOCK (priv); GST_DEBUG ("Starting pipeline"); stateChange = gst_element_set_state (priv->engine.pipeline, GST_STATE_PAUSED); fail_unless (stateChange != GST_STATE_CHANGE_FAILURE); /* wait for completion of the move to PAUSED */ stateChange = gst_element_get_state (priv->engine.pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (stateChange != GST_STATE_CHANGE_FAILURE); g_idle_add ((GSourceFunc) start_pipeline_playing, priv); /* block until a callback calls g_main_loop_quit (engine.loop) */ GST_DEBUG ("main thread waiting for streams to finish"); g_main_loop_run (priv->engine.loop); GST_DEBUG ("main thread finished. Stopping pipeline"); /* no need to use gst_element_get_state as the move the GST_STATE_NULL is always synchronous */ stateChange = gst_element_set_state (priv->engine.pipeline, GST_STATE_NULL); fail_unless (stateChange != GST_STATE_CHANGE_FAILURE); GST_TEST_LOCK (priv); /* call a test callback after the stop of the pipeline */ if (callbacks->post_test) (*callbacks->post_test) (&priv->engine, priv->user_data); g_signal_handlers_disconnect_by_func (bus, G_CALLBACK (on_ErrorMessageOnBus), priv); gst_bus_remove_signal_watch (bus); g_signal_handlers_disconnect_by_func (demux, G_CALLBACK (on_demuxNewPad), priv); g_signal_handlers_disconnect_by_func (demux, G_CALLBACK (on_demuxPadRemoved), priv); GST_DEBUG ("main thread pipeline stopped"); if (priv->clock_update_id != 0) g_source_remove (priv->clock_update_id); gst_object_unref (priv->engine.clock); gst_object_unref (priv->engine.pipeline); priv->engine.pipeline = NULL; g_main_loop_unref (priv->engine.loop); g_ptr_array_unref (priv->engine.output_streams); gst_object_unref (bus); GST_TEST_UNLOCK (priv); g_mutex_clear (&priv->engine.lock); g_slice_free (GstAdaptiveDemuxTestEnginePrivate, priv); }