static gboolean gst_adaptive_demux_update_test_clock (gpointer user_data) { GstAdaptiveDemuxTestEnginePrivate *priv = (GstAdaptiveDemuxTestEnginePrivate *) user_data; GstClockID id; GstClockTime next_entry; GstTestClock *clock = GST_TEST_CLOCK (priv->engine.clock); fail_unless (clock != NULL); next_entry = gst_test_clock_get_next_entry_time (clock); if (next_entry != GST_CLOCK_TIME_NONE) { /* tests that do not want the manifest to update will set the update period * to a big value, eg 500s. The manifest update task will register an alarm * for that value. * We do not want the clock to jump to that. If it does, the manifest update * task will keep scheduling and use all the cpu power, starving the other * threads. * Usually the test require the clock to update with approx 3s, so we will * allow only updates smaller than 100s */ GstClockTime curr_time = gst_clock_get_time (GST_CLOCK (clock)); if (next_entry - curr_time < 100 * GST_SECOND) { gst_test_clock_set_time (clock, next_entry); id = gst_test_clock_process_next_clock_id (clock); fail_unless (id != NULL); gst_clock_id_unref (id); } } return TRUE; }
static GstClockReturn gst_test_clock_wait_async (GstClock * clock, GstClockEntry * entry) { GstTestClock *test_clock = GST_TEST_CLOCK (clock); GST_OBJECT_LOCK (test_clock); if (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED) goto was_unscheduled; GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "requesting asynchronous clock notification at %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry))); gst_test_clock_add_entry (test_clock, entry, NULL); GST_OBJECT_UNLOCK (test_clock); return GST_CLOCK_OK; /* ERRORS */ was_unscheduled: { GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "entry was unscheduled"); GST_OBJECT_UNLOCK (test_clock); return GST_CLOCK_UNSCHEDULED; } }
static void gst_test_clock_constructed (GObject * object) { GstTestClock *test_clock = GST_TEST_CLOCK (object); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); priv->internal_time = priv->start_time; G_OBJECT_CLASS (parent_class)->constructed (object); }
static void gst_test_clock_finalize (GObject * object) { GstTestClock *test_clock = GST_TEST_CLOCK (object); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); g_cond_clear (&priv->entry_added_cond); g_cond_clear (&priv->entry_processed_cond); G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gst_test_clock_unschedule (GstClock * clock, GstClockEntry * entry) { GstTestClock *test_clock = GST_TEST_CLOCK (clock); GST_OBJECT_LOCK (test_clock); GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "unscheduling requested clock notification at %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry))); GST_CLOCK_ENTRY_STATUS (entry) = GST_CLOCK_UNSCHEDULED; gst_test_clock_remove_entry (test_clock, entry); GST_OBJECT_UNLOCK (test_clock); }
static void gst_test_clock_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GstTestClock *test_clock = GST_TEST_CLOCK (object); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); switch (property_id) { case PROP_START_TIME: g_value_set_uint64 (value, priv->start_time); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static void gst_test_clock_dispose (GObject * object) { GstTestClock *test_clock = GST_TEST_CLOCK (object); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); GST_OBJECT_LOCK (test_clock); while (priv->entry_contexts != NULL) { GstClockEntryContext *ctx = priv->entry_contexts->data; gst_test_clock_remove_entry (test_clock, ctx->clock_entry); } GST_OBJECT_UNLOCK (test_clock); G_OBJECT_CLASS (parent_class)->dispose (object); }
static GstClockTime gst_test_clock_get_internal_time (GstClock * clock) { GstTestClock *test_clock = GST_TEST_CLOCK (clock); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); GstClockTime result; GST_OBJECT_LOCK (test_clock); GST_CAT_TRACE_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "retrieving test clock time %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->internal_time)); result = priv->internal_time; GST_OBJECT_UNLOCK (test_clock); return result; }
static void gst_test_clock_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { GstTestClock *test_clock = GST_TEST_CLOCK (object); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); switch (property_id) { case PROP_START_TIME: priv->start_time = g_value_get_uint64 (value); GST_CAT_TRACE_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "test clock start time initialized at %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->start_time)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static GstClockReturn gst_test_clock_wait (GstClock * clock, GstClockEntry * entry, GstClockTimeDiff * jitter) { GstTestClock *test_clock = GST_TEST_CLOCK (clock); GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock); GST_OBJECT_LOCK (test_clock); GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "requesting synchronous clock notification at %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry))); if (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED) goto was_unscheduled; if (gst_test_clock_lookup_entry_context (test_clock, entry) == NULL) gst_test_clock_add_entry (test_clock, entry, jitter); GST_CLOCK_ENTRY_STATUS (entry) = GST_CLOCK_BUSY; while (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_BUSY) g_cond_wait (&priv->entry_processed_cond, GST_OBJECT_GET_LOCK (test_clock)); GST_OBJECT_UNLOCK (test_clock); return GST_CLOCK_ENTRY_STATUS (entry); /* ERRORS */ was_unscheduled: { GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock, "entry was unscheduled"); GST_OBJECT_UNLOCK (test_clock); return GST_CLOCK_UNSCHEDULED; } }