* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/9d/9db09c8c466c80d9569deb7379732f47eaebe51b.svn-base b/jni/pjproject-android/.svn/pristine/9d/9db09c8c466c80d9569deb7379732f47eaebe51b.svn-base
new file mode 100644
index 0000000..3423bf2
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/9d/9db09c8c466c80d9569deb7379732f47eaebe51b.svn-base
@@ -0,0 +1,426 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia/clock.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/lock.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+#include <pj/compat/high_precision.h>
+
+/* API: Init clock source */
+PJ_DEF(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,
+                                            pjmedia_type media_type,
+                                            unsigned clock_rate,
+                                            unsigned ptime_usec )
+{
+    PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);
+
+    clocksrc->media_type = media_type;
+    clocksrc->clock_rate = clock_rate;
+    clocksrc->ptime_usec = ptime_usec;
+    pj_set_timestamp32(&clocksrc->timestamp, 0, 0);
+    pj_get_timestamp(&clocksrc->last_update);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Update clock source */
+PJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,
+                                               const pj_timestamp *timestamp )
+{
+    PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);
+
+    if (timestamp)
+        pj_memcpy(&clocksrc->timestamp, timestamp, sizeof(pj_timestamp));
+    pj_get_timestamp(&clocksrc->last_update);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Get clock source's current timestamp */
+PJ_DEF(pj_status_t)
+pjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,
+                                         pj_timestamp *timestamp)
+{
+    pj_timestamp now;
+    unsigned elapsed_ms;
+    
+    PJ_ASSERT_RETURN(clocksrc && timestamp, PJ_EINVAL);
+
+    pj_get_timestamp(&now);
+    elapsed_ms = pj_elapsed_msec(&clocksrc->last_update, &now);
+    pj_memcpy(timestamp, &clocksrc->timestamp, sizeof(pj_timestamp));
+    pj_add_timestamp32(timestamp, elapsed_ms * clocksrc->clock_rate / 1000);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Get clock source's time (in ms) */
+PJ_DEF(pj_uint32_t)
+pjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc )
+{
+    pj_timestamp ts;
+
+    pjmedia_clock_src_get_current_timestamp(clocksrc, &ts);
+
+#if PJ_HAS_INT64
+    if (ts.u64 > PJ_UINT64(0x3FFFFFFFFFFFFF))
+        return (pj_uint32_t)(ts.u64 / clocksrc->clock_rate * 1000);
+    else
+        return (pj_uint32_t)(ts.u64 * 1000 / clocksrc->clock_rate);
+#elif PJ_HAS_FLOATING_POINT
+    return (pj_uint32_t)((1.0 * ts.u32.hi * 0xFFFFFFFFUL + ts.u32.lo)
+                         * 1000.0 / clocksrc->clock_rate);
+#else
+    if (ts.u32.lo > 0x3FFFFFUL)
+        return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi 
+                             * 1000UL + ts.u32.lo / clocksrc->clock_rate *
+                             1000UL);
+    else
+        return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi 
+                             * 1000UL + ts.u32.lo * 1000UL /
+                             clocksrc->clock_rate);
+#endif
+}
+
+
+/*
+ * Implementation of media clock with OS thread.
+ */
+
+struct pjmedia_clock
+{
+    pj_pool_t		    *pool;
+    pj_timestamp	     freq;
+    pj_timestamp	     interval;
+    pj_timestamp	     next_tick;
+    pj_timestamp	     timestamp;
+    unsigned		     timestamp_inc;
+    unsigned		     options;
+    pj_uint64_t		     max_jump;
+    pjmedia_clock_callback  *cb;
+    void		    *user_data;
+    pj_thread_t		    *thread;
+    pj_bool_t		     running;
+    pj_bool_t		     quitting;
+    pj_lock_t		    *lock;
+};
+
+
+static int clock_thread(void *arg);
+
+#define MAX_JUMP_MSEC	500
+#define USEC_IN_SEC	(pj_uint64_t)1000000
+
+/*
+ * Create media clock.
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
+					  unsigned clock_rate,
+					  unsigned channel_count,
+					  unsigned samples_per_frame,
+					  unsigned options,
+					  pjmedia_clock_callback *cb,
+					  void *user_data,
+					  pjmedia_clock **p_clock)
+{
+    pjmedia_clock_param param;
+
+    param.usec_interval = (unsigned)(samples_per_frame * USEC_IN_SEC /
+			             channel_count / clock_rate);
+    param.clock_rate = clock_rate;
+    return pjmedia_clock_create2(pool, &param, options, cb,
+                                 user_data, p_clock);
+}
+
+PJ_DEF(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
+                                          const pjmedia_clock_param *param,
+				          unsigned options,
+				          pjmedia_clock_callback *cb,
+				          void *user_data,
+				          pjmedia_clock **p_clock)
+{
+    pjmedia_clock *clock;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(pool && param->usec_interval && param->clock_rate &&
+                     p_clock, PJ_EINVAL);
+
+    clock = PJ_POOL_ALLOC_T(pool, pjmedia_clock);
+    clock->pool = pj_pool_create(pool->factory, "clock%p", 512, 512, NULL);
+
+    status = pj_get_timestamp_freq(&clock->freq);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+                          USEC_IN_SEC;
+    clock->next_tick.u64 = 0;
+    clock->timestamp.u64 = 0;
+    clock->max_jump = MAX_JUMP_MSEC * clock->freq.u64 / 1000;
+    clock->timestamp_inc = (unsigned)(param->usec_interval *
+                                      param->clock_rate /
+				      USEC_IN_SEC);
+    clock->options = options;
+    clock->cb = cb;
+    clock->user_data = user_data;
+    clock->thread = NULL;
+    clock->running = PJ_FALSE;
+    clock->quitting = PJ_FALSE;
+    
+    /* I don't think we need a mutex, so we'll use null. */
+    status = pj_lock_create_null_mutex(pool, "clock", &clock->lock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    *p_clock = clock;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Start the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock)
+{
+    pj_timestamp now;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    if (clock->running)
+	return PJ_SUCCESS;
+
+    status = pj_get_timestamp(&now);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    clock->next_tick.u64 = now.u64 + clock->interval.u64;
+    clock->running = PJ_TRUE;
+    clock->quitting = PJ_FALSE;
+
+    if ((clock->options & PJMEDIA_CLOCK_NO_ASYNC) == 0 && !clock->thread) {
+	status = pj_thread_create(clock->pool, "clock", &clock_thread, clock,
+				  0, 0, &clock->thread);
+	if (status != PJ_SUCCESS) {
+	    clock->running = PJ_FALSE;
+	    return status;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Stop the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)
+{
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    clock->running = PJ_FALSE;
+    clock->quitting = PJ_TRUE;
+
+    if (clock->thread) {
+	if (pj_thread_join(clock->thread) == PJ_SUCCESS) {
+	    pj_thread_destroy(clock->thread);
+	    clock->thread = NULL;
+	    pj_pool_reset(clock->pool);
+	} else {
+	    clock->quitting = PJ_FALSE;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Update the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+                                         const pjmedia_clock_param *param)
+{
+    clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+                          USEC_IN_SEC;
+    clock->timestamp_inc = (unsigned)(param->usec_interval *
+                                      param->clock_rate /
+				      USEC_IN_SEC);
+
+    return PJ_SUCCESS;
+}
+
+
+/* Calculate next tick */
+PJ_INLINE(void) clock_calc_next_tick(pjmedia_clock *clock,
+				     pj_timestamp *now)
+{
+    if (clock->next_tick.u64+clock->max_jump < now->u64) {
+	/* Timestamp has made large jump, adjust next_tick */
+	clock->next_tick.u64 = now->u64;
+    }
+    clock->next_tick.u64 += clock->interval.u64;
+
+}
+
+/*
+ * Poll the clock. 
+ */
+PJ_DEF(pj_bool_t) pjmedia_clock_wait( pjmedia_clock *clock,
+				      pj_bool_t wait,
+				      pj_timestamp *ts)
+{
+    pj_timestamp now;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(clock != NULL, PJ_FALSE);
+    PJ_ASSERT_RETURN((clock->options & PJMEDIA_CLOCK_NO_ASYNC) != 0,
+		     PJ_FALSE);
+    PJ_ASSERT_RETURN(clock->running, PJ_FALSE);
+
+    status = pj_get_timestamp(&now);
+    if (status != PJ_SUCCESS)
+	return PJ_FALSE;
+
+    /* Wait for the next tick to happen */
+    if (now.u64 < clock->next_tick.u64) {
+	unsigned msec;
+
+	if (!wait)
+	    return PJ_FALSE;
+
+	msec = pj_elapsed_msec(&now, &clock->next_tick);
+	pj_thread_sleep(msec);
+    }
+
+    /* Call callback, if any */
+    if (clock->cb)
+	(*clock->cb)(&clock->timestamp, clock->user_data);
+
+    /* Report timestamp to caller */
+    if (ts)
+	ts->u64 = clock->timestamp.u64;
+
+    /* Increment timestamp */
+    clock->timestamp.u64 += clock->timestamp_inc;
+
+    /* Calculate next tick */
+    clock_calc_next_tick(clock, &now);
+
+    /* Done */
+    return PJ_TRUE;
+}
+
+
+/*
+ * Clock thread
+ */
+static int clock_thread(void *arg)
+{
+    pj_timestamp now;
+    pjmedia_clock *clock = (pjmedia_clock*) arg;
+
+    /* Set thread priority to maximum unless not wanted. */
+    if ((clock->options & PJMEDIA_CLOCK_NO_HIGHEST_PRIO) == 0) {
+	int max = pj_thread_get_prio_max(pj_thread_this());
+	if (max > 0)
+	    pj_thread_set_prio(pj_thread_this(), max);
+    }
+
+    /* Get the first tick */
+    pj_get_timestamp(&clock->next_tick);
+    clock->next_tick.u64 += clock->interval.u64;
+
+
+    while (!clock->quitting) {
+
+	pj_get_timestamp(&now);
+
+	/* Wait for the next tick to happen */
+	if (now.u64 < clock->next_tick.u64) {
+	    unsigned msec;
+	    msec = pj_elapsed_msec(&now, &clock->next_tick);
+	    pj_thread_sleep(msec);
+	}
+
+	/* Skip if not running */
+	if (!clock->running) {
+	    /* Calculate next tick */
+	    clock_calc_next_tick(clock, &now);
+	    continue;
+	}
+
+	pj_lock_acquire(clock->lock);
+
+	/* Call callback, if any */
+	if (clock->cb)
+	    (*clock->cb)(&clock->timestamp, clock->user_data);
+
+	/* Best effort way to detect if we've been destroyed in the callback */
+	if (clock->quitting)
+	    break;
+
+	/* Increment timestamp */
+	clock->timestamp.u64 += clock->timestamp_inc;
+
+	/* Calculate next tick */
+	clock_calc_next_tick(clock, &now);
+
+	pj_lock_release(clock->lock);
+    }
+
+    return 0;
+}
+
+
+/*
+ * Destroy the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock)
+{
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    clock->running = PJ_FALSE;
+    clock->quitting = PJ_TRUE;
+
+    if (clock->thread) {
+	pj_thread_join(clock->thread);
+	pj_thread_destroy(clock->thread);
+	clock->thread = NULL;
+    }
+
+    if (clock->lock) {
+	pj_lock_destroy(clock->lock);
+	clock->lock = NULL;
+    }
+
+    if (clock->pool) {
+	pj_pool_t *pool = clock->pool;
+	clock->pool = NULL;
+	pj_pool_release(pool);
+    }
+    return PJ_SUCCESS;
+}
+
+