예제 #1
0
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); 
}
예제 #2
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;
}
예제 #3
0
/* 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);
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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);
}
예제 #7
0
/* 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;
}
예제 #8
0
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);
}
예제 #9
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);
}
예제 #10
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);
}
예제 #11
0
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);
}
예제 #12
0
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);
}
예제 #13
0
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);
}
예제 #14
0
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);
}