* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/05/051fef84896e76c3f43c27daba87fedab537faf5.svn-base b/jni/pjproject-android/.svn/pristine/05/051fef84896e76c3f43c27daba87fedab537faf5.svn-base
new file mode 100644
index 0000000..4298aa3
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/051fef84896e76c3f43c27daba87fedab537faf5.svn-base
@@ -0,0 +1,766 @@
+/* $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 "test.h"
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+
+#if INCLUDE_ENCRYPTION_TEST
+
+/*
+ * Encryption algorithm tests.
+ */
+#define THIS_FILE   "encryption.c"
+
+
+/*
+ * SHA1 test from the original sha1.c source file.
+ */
+static char *sha1_test_data[] = {
+    "abc",
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+    "A million repetitions of 'a'"
+};
+static char *sha1_test_results[] = {
+    "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
+    "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
+    "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"
+};
+
+
+static void digest_to_hex(const pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE], 
+			  char *output)
+{
+    int i,j;
+    char *c = output;
+    
+    for (i = 0; i < PJ_SHA1_DIGEST_SIZE/4; i++) {
+        for (j = 0; j < 4; j++) {
+            sprintf(c,"%02X", digest[i*4+j]);
+            c += 2;
+        }
+        sprintf(c, " ");
+        c += 1;
+    }
+    *(c - 1) = '\0';
+}
+
+static int sha1_test1(void)
+{
+    enum { MILLION = 1000000 };
+    int k;
+    pj_sha1_context context;
+    pj_uint8_t digest[20];
+    char output[80];
+    pj_pool_t *pool;
+    pj_uint8_t *block;
+
+    PJ_LOG(3, (THIS_FILE, "  SHA1 test vector 1 from sha1.c.."));
+    
+    for (k = 0; k < 2; k++){ 
+        pj_sha1_init(&context);
+        pj_sha1_update(&context, (pj_uint8_t*)sha1_test_data[k], 
+		       pj_ansi_strlen(sha1_test_data[k]));
+        pj_sha1_final(&context, digest);
+	digest_to_hex(digest, output);
+
+        if (pj_ansi_strcmp(output, sha1_test_results[k])) {
+	    PJ_LOG(3, (THIS_FILE, "    incorrect hash result on k=%d", k));
+            return -10;
+        }
+    }
+
+    /* million 'a' vector we feed separately */
+    pj_sha1_init(&context);
+    for (k = 0; k < MILLION; k++)
+        pj_sha1_update(&context, (pj_uint8_t*)"a", 1);
+    pj_sha1_final(&context, digest);
+    digest_to_hex(digest, output);
+    if (strcmp(output, sha1_test_results[2])) {
+	PJ_LOG(3, (THIS_FILE, "    incorrect hash result!"));
+        return -20;
+    }
+
+    /* million 'a' test, using block */
+    pool = pj_pool_create(mem, "sha1test", 256, 512, NULL);
+    block = (pj_uint8_t*)pj_pool_alloc(pool, MILLION);
+    pj_memset(block, 'a', MILLION);
+
+    pj_sha1_init(&context);
+    pj_sha1_update(&context, block, MILLION);
+    pj_sha1_final(&context, digest);
+    digest_to_hex(digest, output);
+    if (strcmp(output, sha1_test_results[2])) {
+	pj_pool_release(pool);
+	PJ_LOG(3, (THIS_FILE, "    incorrect hash result for block update!"));
+        return -21;
+    }
+
+    /* verify that original buffer was not modified */
+    for (k=0; k<MILLION; ++k) {
+	if (block[k] != 'a') {
+	    pj_pool_release(pool);
+	    PJ_LOG(3, (THIS_FILE, "    block was modified!"));
+	    return -22;
+	}
+    }
+
+    pj_pool_release(pool);
+
+    /* success */
+    return(0);
+}
+
+
+/*
+ * SHA1 test from RFC 3174
+ */
+/*
+ *  Define patterns for testing
+ */
+#define TEST1   "abc"
+#define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
+#define TEST2b  "jkijkljklmklmnlmnomnopnopq"
+#define TEST2   TEST2a TEST2b
+#define TEST3   "a"
+#define TEST4a  "01234567012345670123456701234567"
+#define TEST4b  "01234567012345670123456701234567"
+    /* an exact multiple of 512 bits */
+#define TEST4   TEST4a TEST4b
+
+static char *testarray[4] =
+{
+    TEST1,
+    TEST2,
+    TEST3,
+    TEST4
+};
+static int repeatcount[4] = { 1, 1, 1000000, 10 };
+static char *resultarray[4] =
+{
+    "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
+    "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
+    "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F",
+    "DEA356A2 CDDD90C7 A7ECEDC5 EBB56393 4F460452"
+};
+
+static int sha1_test2(void)
+{
+    pj_sha1_context sha;
+    int i;
+    pj_uint8_t digest[20];
+    char char_digest[64];
+
+    PJ_LOG(3, (THIS_FILE, "  SHA1 test vector 2 from rfc 3174.."));
+
+    for(i = 0; i < 4; ++i) {
+	int j;
+
+        pj_sha1_init(&sha);
+
+        for(j = 0; j < repeatcount[i]; ++j) {
+            pj_sha1_update(&sha,
+			   (const pj_uint8_t *) testarray[i],
+			   pj_ansi_strlen(testarray[i]));
+        }
+
+        pj_sha1_final(&sha, digest);
+
+	digest_to_hex(digest, char_digest);
+	if (pj_ansi_strcmp(char_digest, resultarray[i])) {
+	    PJ_LOG(3, (THIS_FILE, "    digest mismatch in test %d", i));
+	    return -40;
+	}
+    }
+
+    return 0;
+}
+
+
+/*
+ * HMAC-MD5 and HMAC-SHA1 test vectors from RFC 2202
+ */
+struct rfc2202_test
+{
+    char       *key;
+    unsigned	key_len;
+    char       *input;
+    unsigned	input_len;
+    char       *md5_digest;
+    char       *sha1_digest;
+};
+
+
+struct rfc2202_test rfc2202_test_vector[] = 
+{
+    {
+	"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+	16,
+	"Hi There",
+	8,
+	"\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
+	NULL
+    },
+    {
+	"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+	"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+	20,
+	"Hi There",
+	8,
+	NULL,
+	"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
+    },
+    {
+	"Jefe",
+	4,
+	"what do ya want for nothing?",
+	28,
+	"\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
+	"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
+    },
+    {
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa",
+	16,
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+	50,
+	"\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
+	NULL
+    },
+    {
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+	20,
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+	50,
+	NULL,
+	"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
+    },
+    {
+	"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+	25,
+	"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+	"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+	"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+	"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+	"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+	50,
+	"\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79",
+	"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
+    },
+    {
+	"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+	"\x0c\x0c\x0c\x0c\x0c\x0c",
+	16,
+	"Test With Truncation",
+	20,
+	"\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
+	NULL
+    },
+    {
+	"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+	"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+	20,
+	"Test With Truncation",
+	20,
+	NULL,
+	"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
+    },
+    {
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+	80,
+	"Test Using Larger Than Block-Size Key - Hash Key First",
+	54,
+	"\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
+	"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
+    },
+    {
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+	"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+	80,
+	"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+	73,
+	"\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
+	"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
+    }
+};
+
+
+static int rfc2202_test(void)
+{
+    unsigned i;
+
+    PJ_LOG(3, (THIS_FILE, "  verifying test vectors from rfc 2202.."));
+
+    /* Verify that test vectors are valid */
+    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
+	PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].input) == 
+			    rfc2202_test_vector[i].input_len, -50);
+	PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].key) == 
+			    rfc2202_test_vector[i].key_len, -52);
+	PJ_ASSERT_RETURN(rfc2202_test_vector[i].md5_digest==NULL ||
+			    pj_ansi_strlen(rfc2202_test_vector[i].md5_digest)<=16,
+			    -54);
+	PJ_ASSERT_RETURN(rfc2202_test_vector[i].sha1_digest==NULL ||
+			    pj_ansi_strlen(rfc2202_test_vector[i].sha1_digest)<=20,
+			    -56);
+    }
+
+    /* Test HMAC-MD5 */
+    PJ_LOG(3, (THIS_FILE, "  HMAC-MD5 test vectors from rfc 2202.."));
+    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
+	pj_uint8_t digest_buf[18], *digest;
+
+	if (rfc2202_test_vector[i].md5_digest == NULL)
+	    continue;
+
+	digest_buf[0] = '\0';
+	digest_buf[17] = '\0';
+
+	digest = digest_buf+1;
+
+	pj_hmac_md5((pj_uint8_t*)rfc2202_test_vector[i].input, 
+		    rfc2202_test_vector[i].input_len,
+		    (pj_uint8_t*)rfc2202_test_vector[i].key, 
+		    rfc2202_test_vector[i].key_len,
+		    digest);
+
+	/* Check for overwrites */
+	if (digest_buf[0] != '\0' || digest_buf[17] != '\0') {
+	    PJ_LOG(3, (THIS_FILE, "    error: overwriting outside buffer on test %d", i));
+	    return -60;
+	}
+
+	/* Compare digest */
+	if (pj_memcmp(rfc2202_test_vector[i].md5_digest, digest, 16)) {
+	    PJ_LOG(3, (THIS_FILE, "    error: digest mismatch on test %d", i));
+	    return -65;
+	}
+    }
+
+    /* Test HMAC-SHA1 */
+    PJ_LOG(3, (THIS_FILE, "  HMAC-SHA1 test vectors from rfc 2202.."));
+    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
+	pj_uint8_t digest_buf[22], *digest;
+
+	if (rfc2202_test_vector[i].sha1_digest == NULL)
+	    continue;
+
+	digest_buf[0] = '\0';
+	digest_buf[21] = '\0';
+
+	digest = digest_buf+1;
+
+	pj_hmac_sha1((pj_uint8_t*)rfc2202_test_vector[i].input, 
+		     rfc2202_test_vector[i].input_len,
+		     (pj_uint8_t*)rfc2202_test_vector[i].key, 
+		     rfc2202_test_vector[i].key_len,
+		     digest);
+
+	/* Check for overwrites */
+	if (digest_buf[0] != '\0' || digest_buf[21] != '\0') {
+	    PJ_LOG(3, (THIS_FILE, "    error: overwriting outside buffer on test %d", i));
+	    return -70;
+	}
+
+	/* Compare digest */
+	if (pj_memcmp(rfc2202_test_vector[i].sha1_digest, digest, 20)) {
+	    PJ_LOG(3, (THIS_FILE, "    error: digest mismatch on test %d", i));
+	    return -75;
+	}
+    }
+
+
+    /* Success */
+    return 0;
+}
+
+/* CRC32 test data, generated from crc32 test on a Linux box */
+struct crc32_test_t
+{
+    char	    *input;
+    pj_uint32_t	     crc;
+} crc32_test_data[] = 
+{
+    {
+	"",
+	0x0
+    },
+    {
+	"Hello World",
+	0x4a17b156
+    },
+    {
+	/* Something read from /dev/random */
+	"\x21\x21\x98\x10\x62\x59\xbc\x58\x42\x24\xe5\xf3\x92\x0a\x68\x3c\xa7\x67\x73\xc3",
+	0x506693be
+    },
+    {
+	"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+	0xcab11777
+    },
+    {
+	"123456789",
+	0xCBF43926
+    }
+};
+
+/*
+ * CRC32 test
+ */
+static int crc32_test(void)
+{
+    unsigned i;
+
+    PJ_LOG(3, (THIS_FILE, "  crc32 test.."));
+
+    /* testing pj_crc32_calc */
+    for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) {
+	pj_uint32_t crc;
+
+	crc = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input,
+			    pj_ansi_strlen(crc32_test_data[i].input));
+	if (crc != crc32_test_data[i].crc) {
+	    PJ_LOG(3,(THIS_FILE, "    error: crc mismatch on test %d", i));
+	    return -80;
+	}
+    }
+
+    /* testing incremental CRC32 calculation */
+    for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) {
+	pj_crc32_context ctx;
+	pj_uint32_t crc0, crc1;
+	pj_size_t len;
+
+	len = pj_ansi_strlen(crc32_test_data[i].input);
+	crc0 = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input, len);
+
+	pj_crc32_init(&ctx);
+	pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input,
+			len / 2);
+
+	if (len/2 > 0) {
+	    pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input + len/2,
+			    len - len/2);
+	}
+
+	crc1 = pj_crc32_final(&ctx);
+
+	if (crc0 != crc1) {
+	    PJ_LOG(3,(THIS_FILE, 
+		      "    error: crc algorithm error on test %d", i));
+	    return -85;
+	}
+
+    }
+    return 0;
+}
+
+enum
+{
+    ENCODE = 1,
+    DECODE = 2,
+    ENCODE_DECODE = 3
+};
+
+/*
+ * Base64 test vectors (RFC 4648)
+ */
+static struct base64_test_vec
+{
+    const char *base256;
+    const char *base64;
+    unsigned flag;
+} base64_test_vec[] = 
+{
+    {
+	"",
+	"",
+	ENCODE_DECODE
+    },
+    {
+	"f",
+	"Zg==",
+	ENCODE_DECODE
+    },
+    {
+	"fo",
+	"Zm8=",
+	ENCODE_DECODE
+    },
+    {
+	"foo",
+	"Zm9v",
+	ENCODE_DECODE
+    },
+    {
+	"foob",
+	"Zm9vYg==",
+	ENCODE_DECODE
+    },
+    {
+	"fooba",
+	"Zm9vYmE=",
+	ENCODE_DECODE
+    },
+    {
+	"foobar",
+	"Zm9vYmFy",
+	ENCODE_DECODE
+    },
+    {
+	"\x14\xfb\x9c\x03\xd9\x7e",
+	"FPucA9l+",
+	ENCODE_DECODE
+    },
+    {
+	"\x14\xfb\x9c\x03\xd9",
+	"FPucA9k=",
+	ENCODE_DECODE
+    },
+    {
+	"\x14\xfb\x9c\x03",
+	"FPucAw==",
+	ENCODE_DECODE
+    },
+    /* with whitespaces */
+    {
+	"foobar",
+	"Zm9v\r\nYmFy",
+	DECODE
+    },
+    {
+    	"foobar",
+    	"\nZ\r\nm 9\tv\nYm\nF\ny\n",
+    	DECODE
+    },
+};
+
+
+static int base64_test(void)
+{
+    unsigned i;
+    char output[80];
+    pj_status_t rc;
+
+    PJ_LOG(3, (THIS_FILE, "  base64 test.."));
+
+    for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) {
+	pj_str_t input;
+	int out_len;
+
+	/* Encode test */
+	if (base64_test_vec[i].flag & ENCODE) {
+	    out_len = sizeof(output);
+	    rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256,
+				  (int)strlen(base64_test_vec[i].base256),
+				  output, &out_len);
+	    if (rc != PJ_SUCCESS)
+		return -90;
+
+	    if (out_len != (int)strlen(base64_test_vec[i].base64))
+		return -91;
+
+	    output[out_len] = '\0';
+	    if (strcmp(output, base64_test_vec[i].base64) != 0)
+		return -92;
+	}
+
+	/* Decode test */
+	if (base64_test_vec[i].flag & DECODE) {
+	    out_len = sizeof(output);
+	    input.ptr = (char*)base64_test_vec[i].base64;
+	    input.slen = strlen(base64_test_vec[i].base64);
+	    rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len);
+	    if (rc != PJ_SUCCESS)
+		return -95;
+
+	    if (out_len != (int)strlen(base64_test_vec[i].base256))
+		return -96;
+
+	    output[out_len] = '\0';
+
+	    if (strcmp(output, base64_test_vec[i].base256) != 0)
+		return -97;
+	}
+    }
+
+    return 0;
+}
+
+
+int encryption_test()
+{
+    int rc;
+
+    rc = base64_test();
+    if (rc != 0)
+	return rc;
+
+    rc = sha1_test1();
+    if (rc != 0)
+	return rc;
+
+    rc = sha1_test2();
+    if (rc != 0)
+	return rc;
+
+    rc = rfc2202_test();
+    if (rc != 0)
+	return rc;
+
+    rc = crc32_test();
+    if (rc != 0)
+	return rc;
+
+    return 0;
+}
+
+static void crc32_update(pj_crc32_context *c, const pj_uint8_t *data,
+			 pj_size_t nbytes)
+{
+    pj_crc32_update(c, data, nbytes);
+}
+
+static void crc32_final(pj_crc32_context *ctx, pj_uint32_t *digest)
+{
+    *digest = pj_crc32_final(ctx);
+}
+
+int encryption_benchmark()
+{
+    pj_pool_t *pool;
+    pj_uint8_t *input;
+    union {
+	pj_md5_context md5_context;
+	pj_sha1_context sha1_context;
+    } context;
+    pj_uint8_t digest[32];
+    pj_size_t input_len;
+    struct algorithm
+    {
+	const char *name;
+	void (*init_context)(void*);
+	void (*update)(void*, const pj_uint8_t*, unsigned);
+	void (*final)(void*, void*);
+	pj_uint32_t t;
+    } algorithms[] = 
+    {
+	{
+	    "MD5  ",
+	    (void (*)(void*))&pj_md5_init,
+	    (void (*)(void*, const pj_uint8_t*, unsigned))&pj_md5_update,
+	    (void (*)(void*, void*))&pj_md5_final
+	},
+	{
+	    "SHA1 ",
+	    (void (*)(void*))&pj_sha1_init,
+	    (void (*)(void*, const pj_uint8_t*, unsigned))&pj_sha1_update,
+	    (void (*)(void*, void*))&pj_sha1_final
+	},
+	{
+	    "CRC32",
+	    (void (*)(void*))&pj_crc32_init,
+	    (void (*)(void*, const pj_uint8_t*, unsigned))&crc32_update,
+	    (void (*)(void*, void*))&crc32_final
+	}
+    };
+#if defined(PJ_DEBUG) && PJ_DEBUG!=0
+    enum { LOOP = 1000 };
+#else
+    enum { LOOP = 10000 };
+#endif
+    unsigned i;
+    double total_len;
+
+    input_len = 2048;
+    total_len = (unsigned)input_len * LOOP;
+    pool = pj_pool_create(mem, "enc", input_len+256, 0, NULL);
+    if (!pool)
+	return PJ_ENOMEM;
+
+    input = (pj_uint8_t*)pj_pool_alloc(pool, input_len);
+    pj_memset(input, '\xaa', input_len);
+    
+    PJ_LOG(3, (THIS_FILE, "  feeding %d Mbytes of data",
+	       (unsigned)(total_len/1024/1024)));
+
+    /* Dry run */
+    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
+	algorithms[i].init_context(&context);
+	algorithms[i].update(&context, input, (unsigned)input_len);
+	algorithms[i].final(&context, digest);
+    }
+
+    /* Run */
+    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
+	int j;
+	pj_timestamp t1, t2;
+
+	pj_get_timestamp(&t1);
+	algorithms[i].init_context(&context);
+	for (j=0; j<LOOP; ++j) {
+	    algorithms[i].update(&context, input, (unsigned)input_len);
+	}
+	algorithms[i].final(&context, digest);
+	pj_get_timestamp(&t2);
+
+	algorithms[i].t = pj_elapsed_usec(&t1, &t2);
+    }
+
+    /* Results */
+    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
+	double bytes;
+
+	bytes = (total_len * 1000000 / algorithms[i].t);
+	PJ_LOG(3, (THIS_FILE, "    %s:%8d usec (%3d.%03d Mbytes/sec)",
+		   algorithms[i].name, algorithms[i].t,
+		   (unsigned)(bytes / 1024 / 1024),
+		   ((unsigned)(bytes) % (1024 * 1024)) / 1024));
+    }
+
+    return 0;
+}
+
+
+
+#endif /* INCLUDE_ENCRYPTION_TEST */
+
diff --git a/jni/pjproject-android/.svn/pristine/05/054c48feeef77efa640cf763e8e8af1606922d8c.svn-base b/jni/pjproject-android/.svn/pristine/05/054c48feeef77efa640cf763e8e8af1606922d8c.svn-base
new file mode 100644
index 0000000..2d878cc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/054c48feeef77efa640cf763e8e8af1606922d8c.svn-base
@@ -0,0 +1,1125 @@
+/***************************************************************************
+**
+**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+**   > Software Release 2.1 (2008-06)
+**     (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+**   © 2004 Polycom, Inc.
+**
+**   All rights reserved.
+**
+***************************************************************************/
+
+/***************************************************************************
+  Filename:    encoder.c    
+
+  Purpose:     Contains files used to implement the G.722.1 Annex C encoder
+
+  Design Notes:
+
+***************************************************************************/
+
+/***************************************************************************
+ Include files                                                           
+***************************************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#include "defs.h"
+#include "huff_def.h"
+#include "tables.h"
+#include "count.h"
+
+/***************************************************************************
+ Function:    encoder                                                     
+                                                                         
+ Syntax:      void encoder(Word16 number_of_available_bits,                     
+                           Word16 number_of_regions,
+                           Word16 mlt_coefs,                                        
+                           Word16 mag_shift,                                        
+                           Word16 out_words)                                        
+              
+              inputs:   number_of_available_bits
+                        number_of_regions
+                        mag_shift
+                        mlt_coefs[DCT_LENGTH]
+                        
+              outputs:  out_words[MAX_BITS_PER_FRAME/16]
+                                                                         
+                                                                         
+ Description: Encodes the mlt coefs into out_words using G.722.1 Annex C
+                                                           
+                                                                         
+ WMOPS:     7kHz |    24kbit    |     32kbit
+          -------|--------------|----------------
+            AVG  |    0.93      |     1.04
+          -------|--------------|----------------  
+            MAX  |    1.20      |     1.28
+          -------|--------------|---------------- 
+                                                                        
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    1.39      |     1.71       |     2.01
+          -------|--------------|----------------|----------------
+            MAX  |    2.00      |     2.30       |     2.52
+          -------|--------------|----------------|----------------
+                                                                         
+***************************************************************************/
+
+void encoder(Word16  number_of_available_bits,
+             Word16  number_of_regions,
+             Word16  *mlt_coefs,
+             Word16  mag_shift,
+             Word16  *out_words)
+{
+
+    Word16  num_categorization_control_bits;
+    Word16  num_categorization_control_possibilities;
+    Word16  number_of_bits_per_frame;
+    Word16  number_of_envelope_bits;
+    Word16  categorization_control;
+    Word16  region;
+    Word16  absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
+    Word16  power_categories[MAX_NUMBER_OF_REGIONS];
+    Word16  category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
+    Word16  drp_num_bits[MAX_NUMBER_OF_REGIONS+1];
+    UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1];
+    Word16  region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];
+    UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];
+    Word16  mag_shift_offset;
+
+    Word16 temp;
+
+    /* initialize variables */
+    test();
+    if (number_of_regions == NUMBER_OF_REGIONS)
+    {
+        num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS;
+        move16();
+        num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
+        move16();
+    } 
+    else
+    {
+        num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;
+        move16();
+        num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
+        move16();
+    }
+
+    number_of_bits_per_frame = number_of_available_bits;
+    move16();
+
+    for (region=0; region<number_of_regions; region++)
+    {
+        region_mlt_bit_counts[region] = 0;
+        move16();
+    }
+    
+    /* Estimate power envelope. */
+    number_of_envelope_bits = compute_region_powers(mlt_coefs,
+                                                    mag_shift,
+                                                    drp_num_bits,
+                                                    drp_code_bits,
+                                                    absolute_region_power_index,
+                                                    number_of_regions);
+
+    /* Adjust number of available bits based on power envelope estimate */
+    temp = sub(number_of_available_bits,number_of_envelope_bits);
+    number_of_available_bits = sub(temp,num_categorization_control_bits);
+
+    /* get categorizations */
+    categorize(number_of_available_bits,
+               number_of_regions,
+               num_categorization_control_possibilities,
+               absolute_region_power_index,
+               power_categories,
+               category_balances);
+
+    /* Adjust absolute_region_category_index[] for mag_shift.
+       This assumes that REGION_POWER_STEPSIZE_DB is defined
+       to be exactly 3.010299957 or 20.0 times log base 10
+       of square root of 2. */
+    temp = shl_nocheck(mag_shift,1);
+    mag_shift_offset = add(temp,REGION_POWER_TABLE_NUM_NEGATIVES);
+    
+    for (region=0; region<number_of_regions; region++)
+    {
+        absolute_region_power_index[region] = add(absolute_region_power_index[region],mag_shift_offset);
+        move16();
+    }
+
+    /* adjust the absolute power region index based on the mlt coefs */
+    adjust_abs_region_power_index(absolute_region_power_index,mlt_coefs,number_of_regions);
+
+
+    /* quantize and code the mlt coefficients based on categorizations */
+    vector_quantize_mlts(number_of_available_bits,
+                         number_of_regions,
+                         num_categorization_control_possibilities,
+                         mlt_coefs,
+                         absolute_region_power_index,
+                         power_categories,
+                         category_balances,
+                         &categorization_control,
+                         region_mlt_bit_counts,
+                         region_mlt_bits);
+
+    /* stuff bits into words */
+    bits_to_words(region_mlt_bits,
+                  region_mlt_bit_counts,
+                  drp_num_bits,
+                  drp_code_bits,
+                  out_words,
+                  categorization_control,
+                  number_of_regions,
+                  num_categorization_control_bits,
+                  number_of_bits_per_frame);
+
+}
+
+/***************************************************************************
+ Function:    bits_to_words
+
+ Syntax:      bits_to_words(UWord32 *region_mlt_bits,              
+                            Word16  *region_mlt_bit_counts,                                                             
+                            Word16  *drp_num_bits,                                                                      
+                            UWord16 *drp_code_bits,                                                                     
+                            Word16  *out_words,                                                                         
+                            Word16  categorization_control,                                                                         
+                            Word16  number_of_regions,
+                            Word16  num_categorization_control_bits,
+                            Word16  number_of_bits_per_frame)                                                           
+                                                                   
+                                                                   
+ Description: Stuffs the bits into words for output
+
+ WMOPS:     7kHz |    24kbit    |      32kbit
+          -------|--------------|----------------
+            AVG  |    0.09      |     0.12
+          -------|--------------|----------------  
+            MAX  |    0.10      |     0.13
+          -------|--------------|---------------- 
+          
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    0.12      |     0.15       |     0.19
+          -------|--------------|----------------|----------------
+            MAX  |    0.14      |     0.17       |     0.21
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+void bits_to_words(UWord32 *region_mlt_bits,
+                   Word16  *region_mlt_bit_counts,
+                   Word16  *drp_num_bits,
+                   UWord16 *drp_code_bits,
+                   Word16  *out_words,
+                   Word16  categorization_control,
+                   Word16  number_of_regions,
+                   Word16  num_categorization_control_bits,
+                   Word16  number_of_bits_per_frame)
+{
+    Word16  out_word_index = 0;
+    Word16  j;
+    Word16  region;
+    Word16  out_word;
+    Word16  region_bit_count;
+    Word16  current_word_bits_left;
+    UWord16 slice;
+    Word16  out_word_bits_free = 16;
+    UWord32 *in_word_ptr;
+    UWord32 current_word;
+    
+    Word32  acca = 0;
+    Word32  accb;
+    Word16  temp;
+
+    /* First set up the categorization control bits to look like one more set of region power bits. */
+    out_word = 0;
+    move16();
+
+    drp_num_bits[number_of_regions] = num_categorization_control_bits;
+    move16();
+    
+    drp_code_bits[number_of_regions] = (UWord16)categorization_control;
+    move16();
+
+    /* These code bits are right justified. */
+    for (region=0; region <= number_of_regions; region++)
+    {
+        current_word_bits_left = drp_num_bits[region];
+        move16();
+        
+        current_word = (UWord32)drp_code_bits[region];
+        move16();
+        
+        j = sub(current_word_bits_left,out_word_bits_free);
+
+        test();
+        if (j >= 0)
+        {
+            temp = extract_l(L_shr_nocheck(current_word,j));
+            out_word = add(out_word,temp);
+
+            out_words[out_word_index++] = out_word;
+            move16();
+            
+            out_word_bits_free = 16;
+            move16();
+            
+            out_word_bits_free = sub(out_word_bits_free,j);
+            
+            acca = (current_word << out_word_bits_free);
+            out_word = extract_l(acca);
+        }
+        else
+        {
+            j = negate(j);
+
+            acca = (current_word << j);
+            accb = L_deposit_l(out_word);
+            acca = L_add(accb,acca);
+            out_word = extract_l(acca);
+            
+            out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
+        }
+    }
+
+    /* These code bits are left justified. */
+    
+    for (region=0;region<number_of_regions; region++)
+    {
+        accb = L_deposit_l(out_word_index);
+        accb = L_shl_nocheck(accb,4);
+        accb = L_sub(accb,number_of_bits_per_frame);
+        test();
+        if(accb < 0)        
+        {
+            temp = shl_nocheck(region,2);
+            in_word_ptr = &region_mlt_bits[temp];
+            region_bit_count = region_mlt_bit_counts[region];
+            move16();
+
+            temp = sub(32,region_bit_count);
+            test();
+            if(temp > 0)
+                current_word_bits_left = region_bit_count;
+            else
+                current_word_bits_left = 32;
+
+            current_word = *in_word_ptr++;
+    
+            acca = L_deposit_l(out_word_index);
+            acca = L_shl_nocheck(acca,4);
+            acca = L_sub(acca,number_of_bits_per_frame);
+            
+            /* from while loop */
+            test();
+            test();
+            logic16(); 
+            while ((region_bit_count > 0) && (acca < 0))
+            {
+                /* from while loop */
+                test();
+                test();
+                logic16(); 
+                
+                temp = sub(current_word_bits_left,out_word_bits_free);
+                test();
+                if (temp >= 0)
+                {
+                    temp = sub(32,out_word_bits_free);
+                    accb = LU_shr(current_word,temp);
+                    slice = (UWord16)extract_l(accb);
+                    
+                    out_word = add(out_word,slice);
+    
+                    test();
+                    current_word <<= out_word_bits_free;
+
+                    current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);
+                    out_words[out_word_index++] = extract_l(out_word);
+                    move16();
+
+                    out_word = 0;
+                    move16();
+
+                    out_word_bits_free = 16;
+                    move16();
+                }
+                else
+                {
+                    temp = sub(32,current_word_bits_left);
+                    accb = LU_shr(current_word,temp);
+                    slice = (UWord16)extract_l(accb);
+                    
+                    temp = sub(out_word_bits_free,current_word_bits_left);
+                    test();
+                    accb = slice << temp;
+                    acca = L_deposit_l(out_word);
+                    acca = L_add(acca,accb);
+                    out_word = extract_l(acca);
+                    out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
+                    
+                    current_word_bits_left = 0;
+                    move16();
+                }
+    
+                test();
+                if (current_word_bits_left == 0)
+                {
+                    current_word = *in_word_ptr++;
+                    region_bit_count = sub(region_bit_count,32);
+                    
+                    /* current_word_bits_left = MIN(32,region_bit_count); */
+                    temp = sub(32,region_bit_count);
+                    test();
+                    if(temp > 0)
+                        current_word_bits_left = region_bit_count;
+                    else
+                        current_word_bits_left = 32;
+                    
+                }
+                acca = L_deposit_l(out_word_index);
+                acca = L_shl_nocheck(acca,4);
+                acca = L_sub(acca,number_of_bits_per_frame);
+            }
+            accb = L_deposit_l(out_word_index);
+            accb = L_shl_nocheck(accb,4);
+            accb = L_sub(accb,number_of_bits_per_frame);
+        }
+    }
+
+    /* Fill out with 1's. */
+
+    test();
+    while (acca < 0)
+    {
+        test();
+        current_word = 0x0000ffff;
+        move32();
+
+        temp = sub(16,out_word_bits_free);
+        acca = LU_shr(current_word,temp);
+        slice = (UWord16)extract_l(acca);
+
+        out_word = add(out_word,slice);
+        out_words[out_word_index++] = out_word;
+        move16();
+
+        out_word = 0;
+        move16();
+        
+        out_word_bits_free = 16;
+        move16();
+        
+        acca = L_deposit_l(out_word_index);
+        acca = L_shl_nocheck(acca,4);
+        acca = L_sub(acca,number_of_bits_per_frame);
+    }
+}
+/***************************************************************************
+ Function:    adjust_abs_region_power_index
+
+ Syntax:      adjust_abs_region_power_index(Word16 *absolute_region_power_index,
+                                            Word16 *mlt_coefs,
+                                            Word16 number_of_regions)
+
+              inputs:   *mlt_coefs
+                        *absolute_region_power_index
+                        number_of_regions
+            
+              outputs:  *absolute_region_power_index
+ 
+ Description: Adjusts the absolute power index
+ 
+ 
+ WMOPS:     7kHz |    24kbit    |      32kbit
+          -------|--------------|----------------
+            AVG  |    0.03      |      0.03
+          -------|--------------|----------------  
+            MAX  |    0.12      |      0.12
+          -------|--------------|---------------- 
+
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    0.03      |     0.03       |     0.03
+          -------|--------------|----------------|----------------
+            MAX  |    0.14      |     0.14       |     0.14
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+void adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions)
+{
+    Word16 n,i;
+    Word16 region;
+    Word16 *raw_mlt_ptr;
+    
+    Word32 acca;
+    Word16 temp;
+
+    for (region=0; region<number_of_regions; region++)
+    {
+        n = sub(absolute_region_power_index[region],39);
+        n = shr_nocheck(n,1);
+        
+        test();
+        if (n > 0)
+        {
+            temp = extract_l(L_mult0(region,REGION_SIZE));
+
+            raw_mlt_ptr = &mlt_coefs[temp];
+
+            for (i=0; i<REGION_SIZE; i++)
+            {
+                acca = L_shl_nocheck(*raw_mlt_ptr,16);
+                acca = L_add(acca,32768L);
+                acca = L_shr_nocheck(acca,n);
+                acca = L_shr_nocheck(acca,16);
+                *raw_mlt_ptr++ = extract_l(acca);
+            }
+
+            temp = shl_nocheck(n,1);
+            temp = sub(absolute_region_power_index[region],temp);
+            absolute_region_power_index[region] = temp;
+            move16();
+        }
+    }
+}
+
+/***************************************************************************
+ Function:    compute_region_powers
+
+ Syntax:      Word16 compute_region_powers(Word16  *mlt_coefs,                         
+                                           Word16  mag_shift,                         
+                                           Word16  *drp_num_bits,                      
+                                           UWord16 *drp_code_bits,                     
+                                           Word16  *absolute_region_power_index,       
+                                           Word16  number_of_regions)
+                mlt_coefs[DCT_LENGTH];                      
+                mag_shift;                                          
+                drp_num_bits[MAX_NUMBER_OF_REGIONS];                      
+                drp_code_bits[MAX_NUMBER_OF_REGIONS];                     
+                absolute_region_power_index[MAX_NUMBER_OF_REGIONS];       
+                number_of_regions;
+                                                                   
+ Description: Computes the power for each of the regions
+
+ 
+ WMOPS:     7kHz |    24kbit    |    32kbit
+          -------|--------------|----------------
+            AVG  |    0.09      |    0.09
+          -------|--------------|----------------  
+            MAX  |    0.13      |    0.13
+          -------|--------------|---------------- 
+
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    0.20      |     0.20       |     0.20
+          -------|--------------|----------------|----------------
+            MAX  |    0.29      |     0.29       |     0.29
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+Word16 compute_region_powers(Word16  *mlt_coefs,
+                             Word16  mag_shift,
+                             Word16  *drp_num_bits,
+                             UWord16 *drp_code_bits,
+                             Word16  *absolute_region_power_index,
+                             Word16  number_of_regions)
+{
+
+    Word16 *input_ptr;
+    Word32 long_accumulator;
+    Word16 itemp1;
+    Word16 power_shift;
+    Word16 region;
+    Word16 j;
+    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
+    Word16 number_of_bits;
+    
+    Word32 acca;
+    Word16 temp;
+    Word16 temp1;
+    Word16 temp2;
+
+
+    input_ptr = mlt_coefs;
+    for (region=0; region<number_of_regions; region++)
+    {
+        long_accumulator = L_deposit_l(0);
+
+        for (j=0; j<REGION_SIZE; j++)
+        {
+            itemp1 = *input_ptr++;
+            move16();
+            long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);
+        }
+
+        power_shift = 0;
+        move16();
+
+        acca = (long_accumulator & 0x7fff0000L);
+        logic32();
+
+        test();
+        while (acca > 0)
+        {
+            test();
+            long_accumulator = L_shr_nocheck(long_accumulator,1);
+            
+            acca = (long_accumulator & 0x7fff0000L);
+            logic32();
+
+            power_shift = add(power_shift,1);
+        }
+        
+        acca = L_sub(long_accumulator,32767);
+        
+        temp = add(power_shift,15);
+        test();
+        test();
+        logic16();
+        while ((acca <= 0) && (temp >= 0))
+        {
+            test();
+            test();
+            logic16();
+            
+            long_accumulator = L_shl_nocheck(long_accumulator,1);
+            acca = L_sub(long_accumulator,32767);
+            power_shift--;
+            temp = add(power_shift,15);
+        }
+        long_accumulator = L_shr_nocheck(long_accumulator,1);
+        /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */
+        acca = L_sub(long_accumulator,28963);
+        
+        test();
+        if (acca >= 0)
+            power_shift = add(power_shift,1);
+        
+        acca = L_deposit_l(mag_shift);
+        acca = L_shl_nocheck(acca,1);
+        acca = L_sub(power_shift,acca);
+        acca = L_add(35,acca);
+        acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);
+        absolute_region_power_index[region] = extract_l(acca);
+    }
+
+
+    /* Before we differentially encode the quantized region powers, adjust upward the
+    valleys to make sure all the peaks can be accurately represented. */
+    temp = sub(number_of_regions,2);
+
+    for (region = temp; region >= 0; region--)
+    {
+        temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);
+        temp2 = sub(absolute_region_power_index[region],temp1);
+        test();
+        if (temp2 < 0)
+        {
+            absolute_region_power_index[region] = temp1;
+            move16();
+        }
+    }
+
+    /* The MLT is currently scaled too low by the factor
+       ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).
+       This is the ninth power of 1 over the square root of 2.
+       So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)
+       to drp_code_bits[0]. */
+
+    /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */
+    temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);
+    temp2 = sub(absolute_region_power_index[0],temp1);
+    test();
+    if (temp2 < 0)
+    {
+        absolute_region_power_index[0] = temp1;
+        move16();
+    }
+    
+    temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
+
+	/*
+	 * The next line was corrected in Release 1.2 
+	 */
+
+    temp2 = sub(absolute_region_power_index[0], temp1);  
+    test();
+    if (temp2 > 0)
+    {
+        absolute_region_power_index[0] = temp1;
+        move16();
+    }
+
+    differential_region_power_index[0] = absolute_region_power_index[0];
+    move16();
+    
+    number_of_bits = 5;
+    move16();
+    
+    drp_num_bits[0] = 5;
+    move16();
+    
+    drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);
+    move16();
+
+    /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes
+     may be mathematically impossible anyway.*/
+    for (region=1; region<number_of_regions; region++)
+    {
+        temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);
+        temp2 = sub(absolute_region_power_index[region],temp1);
+        test();
+        if (temp2 < 0)
+        {
+            absolute_region_power_index[region] = temp1;
+            move16();
+        }
+
+        temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
+        temp2 = sub(absolute_region_power_index[region],temp1);
+        test();
+        if (temp2 > 0)
+        {
+            absolute_region_power_index[region] = temp1;
+            move16();
+        }
+    }
+
+    for (region=1; region<number_of_regions; region++)
+    {
+        j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);
+        temp = sub(j,DRP_DIFF_MIN);
+        test();
+        if (temp < 0)
+        {
+            j = DRP_DIFF_MIN;
+        }
+        j = sub(j,DRP_DIFF_MIN);
+        move16();
+        differential_region_power_index[region] = j;
+        move16();
+        
+        temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);
+        temp = add(temp,DRP_DIFF_MIN);
+        absolute_region_power_index[region] = temp;
+        move16();
+
+        number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);
+        drp_num_bits[region] = differential_region_power_bits[region][j];
+        move16();
+        drp_code_bits[region] = differential_region_power_codes[region][j];
+        move16();
+    }
+
+    return (number_of_bits);
+}
+
+/***************************************************************************
+ Function:    vector_quantize_mlts
+
+ Syntax:      void vector_quantize_mlts(number_of_available_bits,
+                                        number_of_regions,                     
+                                        num_categorization_control_possibilities,
+                                        mlt_coefs,                                    
+                                        absolute_region_power_index,                  
+                                        power_categories,                             
+                                        category_balances,                            
+                                        p_categorization_control,                               
+                                        region_mlt_bit_counts,                        
+                                        region_mlt_bits)                              
+                                                                                    
+              Word16 number_of_available_bits;                                        
+              Word16 number_of_regions;
+              Word16 num_categorization_control_possibilities;
+              Word16 mlt_coefs[DCT_LENGTH];                                         
+              Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];                  
+              Word16 power_categories[MAX_NUMBER_OF_REGIONS];                             
+              Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];         
+              Word16 *p_categorization_control;                                                 
+              Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];                        
+              Word32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];                            
+
+ Description: Scalar quantized vector Huffman coding (SQVH)
+
+ 
+ WMOPS:     7kHz |    24kbit    |     32kbit
+          -------|--------------|----------------
+            AVG  |    0.57      |     0.65
+          -------|--------------|----------------  
+            MAX  |    0.78      |     0.83
+          -------|--------------|---------------- 
+
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    0.62      |     0.90       |     1.11
+          -------|--------------|----------------|----------------
+            MAX  |    1.16      |     1.39       |     1.54
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+void vector_quantize_mlts(Word16 number_of_available_bits,
+                          Word16 number_of_regions,
+                          Word16 num_categorization_control_possibilities,
+                          Word16 *mlt_coefs,
+                          Word16 *absolute_region_power_index,
+                          Word16 *power_categories,
+                          Word16 *category_balances,
+                          Word16 *p_categorization_control,
+                          Word16 *region_mlt_bit_counts,
+                          UWord32 *region_mlt_bits)
+{
+
+    Word16 *raw_mlt_ptr;
+    Word16 region;
+    Word16 category;
+    Word16 total_mlt_bits = 0;
+
+    Word16 temp;
+    Word16 temp1;
+    Word16 temp2;
+
+    /* Start in the middle of the categorization control range. */
+    temp = shr_nocheck(num_categorization_control_possibilities,1);
+    temp = sub(temp,1);
+    for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++)
+    {
+        region = category_balances[*p_categorization_control];
+        move16();
+        power_categories[region] = add(power_categories[region],1);
+        move16();
+    }
+
+    for (region=0; region<number_of_regions; region++)
+    {
+        category = power_categories[region];
+        move16();
+        temp = extract_l(L_mult0(region,REGION_SIZE));
+        raw_mlt_ptr = &mlt_coefs[temp];
+        move16();
+        temp = sub(category,(NUM_CATEGORIES-1));
+        test();
+        if (temp < 0)
+        {
+            region_mlt_bit_counts[region] =
+            vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+                           &region_mlt_bits[shl_nocheck(region,2)]);
+        }
+        else
+        {
+            region_mlt_bit_counts[region] = 0;
+            move16();
+        }
+        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+    }
+
+
+    /* If too few bits... */
+    temp = sub(total_mlt_bits,number_of_available_bits);
+    test();
+    test();
+    logic16();
+    while ((temp < 0) && (*p_categorization_control > 0))
+    {
+        test();
+        test();
+        logic16();
+        (*p_categorization_control)--;
+        region = category_balances[*p_categorization_control];
+        move16();
+        
+        power_categories[region] = sub(power_categories[region],1);
+        move16();
+
+        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
+        category = power_categories[region];
+        move16();
+        
+        raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE];
+        move16();
+        
+        temp = sub(category,(NUM_CATEGORIES-1));
+        test();
+        if (temp < 0)
+        {
+            region_mlt_bit_counts[region] =
+                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+                           &region_mlt_bits[shl_nocheck(region,2)]);
+        }
+        else
+        {
+            region_mlt_bit_counts[region] = 0;
+            move16();
+        }
+        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+        temp = sub(total_mlt_bits,number_of_available_bits);
+    }
+
+    /* If too many bits... */
+    /* Set up for while loop test */
+    temp1 = sub(total_mlt_bits,number_of_available_bits);
+    temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
+    test();
+    test();
+    logic16();
+    
+    while ((temp1 > 0) && (temp2 < 0))
+    {
+        /* operations for while contitions */
+        test();
+        test();
+        logic16();
+        
+        region = category_balances[*p_categorization_control];
+        move16();
+        
+        power_categories[region] = add(power_categories[region],1);
+        move16();
+
+        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
+        category = power_categories[region];
+        move16();
+        
+        temp = extract_l(L_mult0(region,REGION_SIZE));
+        raw_mlt_ptr = &mlt_coefs[temp];
+        move16();
+        
+        temp = sub(category,(NUM_CATEGORIES-1));
+        test();
+        if (temp < 0)
+        {
+            region_mlt_bit_counts[region] =
+                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+                           &region_mlt_bits[shl_nocheck(region,2)]);
+        }
+        else
+        {
+            region_mlt_bit_counts[region] = 0;
+            move16();
+        }
+        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+        (*p_categorization_control)++;
+        
+        temp1 = sub(total_mlt_bits,number_of_available_bits);
+        temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
+    }
+}
+
+/***************************************************************************
+ Function:    vector_huffman
+
+ Syntax:      Word16 vector_huffman(Word16  category,     
+                                    Word16  power_index,  
+                                    Word16  *raw_mlt_ptr,  
+                                    UWord32 *word_ptr)     
+                                              
+              inputs:     Word16  category
+                          Word16  power_index
+                          Word16  *raw_mlt_ptr
+             
+              outputs:    number_of_region_bits
+                          *word_ptr
+                                      
+
+ Description: Huffman encoding for each region based on category and power_index  
+
+ WMOPS:     7kHz |    24kbit    |     32kbit
+          -------|--------------|----------------
+            AVG  |    0.03      |     0.03
+          -------|--------------|----------------  
+            MAX  |    0.04      |     0.04
+          -------|--------------|---------------- 
+
+           14kHz |    24kbit    |     32kbit     |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |    0.03      |     0.03       |     0.03
+          -------|--------------|----------------|----------------
+            MAX  |    0.04      |     0.04       |     0.04
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+Word16 vector_huffman(Word16 category,
+                      Word16 power_index,
+                      Word16 *raw_mlt_ptr,
+                      UWord32 *word_ptr)
+{
+ 
+
+    Word16  inv_of_step_size_times_std_dev;
+    Word16  j,n;
+    Word16  k;
+    Word16  number_of_region_bits;
+    Word16  number_of_non_zero;
+    Word16  vec_dim;
+    Word16  num_vecs;
+    Word16  kmax, kmax_plus_one;
+    Word16  index,signs_index;
+    Word16  *bitcount_table_ptr;
+    UWord16 *code_table_ptr;
+    Word32  code_bits;
+    Word16  number_of_code_bits;
+    UWord32 current_word;
+    Word16  current_word_bits_free;
+    
+    Word32 acca;
+    Word32 accb;
+    Word16 temp;
+
+    Word16 mytemp;			 /* new variable in Release 1.2 */
+    Word16 myacca;			 /* new variable in Release 1.2 */
+
+
+    /* initialize variables */
+    vec_dim = vector_dimension[category];
+    move16();
+
+    num_vecs = number_of_vectors[category];
+    move16();
+
+    kmax = max_bin[category];
+    move16();
+
+    kmax_plus_one = add(kmax,1);
+    move16();
+
+    current_word = 0L;
+    move16();
+
+    current_word_bits_free = 32;
+    move16();
+
+    number_of_region_bits = 0;
+    move16();
+
+    /* set up table pointers */
+    bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];
+    code_table_ptr = (UWord16 *) table_of_code_tables[category];
+
+    /* compute inverse of step size * standard deviation */
+    acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);
+    acca = L_shr_nocheck(acca,1);
+    acca = L_add(acca,4096);
+    acca = L_shr_nocheck(acca,13);
+
+	/*
+	 *  The next two lines are new to Release 1.2 
+	 */
+     
+	mytemp = (Word16)(acca & 0x3);
+    acca = L_shr_nocheck(acca,2);
+
+    inv_of_step_size_times_std_dev = extract_l(acca);
+
+
+    for (n=0; n<num_vecs; n++)
+    {
+        index = 0;
+        move16();
+        
+        signs_index = 0;
+        move16();
+        
+        number_of_non_zero = 0;
+        move16();
+        
+        for (j=0; j<vec_dim; j++)
+        {
+            k = abs_s(*raw_mlt_ptr);
+            
+            acca = L_mult(k,inv_of_step_size_times_std_dev);
+            acca = L_shr_nocheck(acca,1);
+		    
+			/*
+			 *  The next four lines are new to Release 1.2
+			 */
+
+			myacca = (Word16)L_mult(k,mytemp);
+			myacca = (Word16)L_shr_nocheck(myacca,1);
+			myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);
+			myacca = (Word16)L_shr_nocheck(myacca,2);
+
+            acca = L_add(acca,int_dead_zone[category]);
+
+			/*
+			 *  The next two lines are new to Release 1.2
+			 */
+
+			acca = L_add(acca,myacca);
+			acca = L_shr_nocheck(acca,13);
+
+            k = extract_l(acca);
+
+            test();
+            if (k != 0)
+            {
+                number_of_non_zero = add(number_of_non_zero,1);
+                signs_index = shl_nocheck(signs_index,1);
+                
+                test();
+                if (*raw_mlt_ptr > 0)
+                {
+                    signs_index = add(signs_index,1);
+                }
+                
+                temp = sub(k,kmax);
+                test();
+                if (temp > 0)
+                {
+                    k = kmax;
+                    move16();
+                }
+            }
+            acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1);
+            index = extract_l(acca);
+            index = add(index,k);
+            raw_mlt_ptr++;
+        }
+
+        code_bits = *(code_table_ptr+index);
+        number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);
+        number_of_region_bits = add(number_of_region_bits,number_of_code_bits);
+
+        acca = code_bits << number_of_non_zero;
+        accb = L_deposit_l(signs_index);
+        acca = L_add(acca,accb);
+        code_bits = acca;
+        move32();
+
+        /* msb of codebits is transmitted first. */
+        j = sub(current_word_bits_free,number_of_code_bits);
+        test();
+        if (j >= 0)
+        {
+            test();
+            acca = code_bits << j;
+            current_word = L_add(current_word,acca);
+            current_word_bits_free = j;
+            move16();
+        }
+        else
+        {
+            j = negate(j);
+            acca = L_shr_nocheck(code_bits,j);
+            current_word = L_add(current_word,acca);
+            
+            *word_ptr++ = current_word;
+            move16();
+
+            current_word_bits_free = sub(32,j);
+            test();
+            current_word = code_bits << current_word_bits_free;
+        }
+    }
+
+    *word_ptr++ = current_word;
+    move16();
+
+    return (number_of_region_bits);
+}
+
+
diff --git a/jni/pjproject-android/.svn/pristine/05/054e12b694c21a1058972c51dd19464722ddba22.svn-base b/jni/pjproject-android/.svn/pristine/05/054e12b694c21a1058972c51dd19464722ddba22.svn-base
new file mode 100644
index 0000000..542d266
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/054e12b694c21a1058972c51dd19464722ddba22.svn-base
@@ -0,0 +1,250 @@
+/* $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 "test.h"
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-codec/ffmpeg_vid_codecs.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia_videodev.h>
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+#define THIS_FILE 	"vid_dev_test.c"
+#define LOOP_DURATION	6
+
+static pj_bool_t is_quitting = PJ_FALSE;
+
+static pj_status_t vid_event_cb(pjmedia_event *event,
+                                void *user_data)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (event->type == PJMEDIA_EVENT_WND_CLOSED)
+        is_quitting = PJ_TRUE;
+
+    return PJ_SUCCESS;
+}
+
+static int capture_render_loopback(pj_bool_t active,
+				   int cap_dev_id, int rend_dev_id,
+                                   const pjmedia_format *fmt)
+{
+    pj_pool_t *pool;
+    pjmedia_vid_port *capture=NULL, *renderer=NULL;
+    pjmedia_vid_dev_info cdi, rdi;
+    pjmedia_vid_port_param param;
+    pjmedia_video_format_detail *vfd;
+    pj_status_t status;
+    int rc = 0, i;
+
+    pool = pj_pool_create(mem, "vidportloop", 1000, 1000, NULL);
+
+    status = pjmedia_vid_dev_get_info(cap_dev_id, &cdi);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    status = pjmedia_vid_dev_get_info(rend_dev_id, &rdi);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    PJ_LOG(3,(THIS_FILE,
+	      "  %s (%s) ===> %s (%s)\t%s\t%dx%d\t@%d:%d fps",
+	      cdi.name, cdi.driver, rdi.name, rdi.driver,
+	      pjmedia_get_video_format_info(NULL, fmt->id)->name,
+	      fmt->det.vid.size.w, fmt->det.vid.size.h,
+	      fmt->det.vid.fps.num, fmt->det.vid.fps.denum));
+
+    pjmedia_vid_port_param_default(&param);
+
+    /* Create capture, set it to active (master) */
+    status = pjmedia_vid_dev_default_param(pool, cap_dev_id,
+					   &param.vidparam);
+    if (status != PJ_SUCCESS) {
+	rc = 100; goto on_return;
+    }
+    param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+    param.vidparam.fmt = *fmt;
+    param.active = (active? PJ_TRUE: PJ_FALSE);
+
+    if (param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
+	rc = 103; goto on_return;
+    }
+
+    vfd = pjmedia_format_get_video_format_detail(&param.vidparam.fmt, PJ_TRUE);
+    if (vfd == NULL) {
+	rc = 105; goto on_return;
+    }
+
+    status = pjmedia_vid_port_create(pool, &param, &capture);
+    if (status != PJ_SUCCESS) {
+	rc = 110; goto on_return;
+    }
+
+    /* Create renderer, set it to passive (slave)  */
+    status = pjmedia_vid_dev_default_param(pool, rend_dev_id,
+					   &param.vidparam);
+    if (status != PJ_SUCCESS) {
+	rc = 120; goto on_return;
+    }
+
+    param.active = (active? PJ_FALSE: PJ_TRUE);
+    param.vidparam.dir = PJMEDIA_DIR_RENDER;
+    param.vidparam.rend_id = rend_dev_id;
+    param.vidparam.fmt = *fmt;
+    param.vidparam.disp_size = vfd->size;
+
+    status = pjmedia_vid_port_create(pool, &param, &renderer);
+    if (status != PJ_SUCCESS) {
+	rc = 130; goto on_return;
+    }
+
+    /* Set event handler */
+    pjmedia_event_subscribe(NULL, &vid_event_cb, NULL, renderer);
+
+    /* Connect capture to renderer */
+    status = pjmedia_vid_port_connect(
+	         (active? capture: renderer),
+		 pjmedia_vid_port_get_passive_port(active? renderer: capture),
+		 PJ_FALSE);
+    if (status != PJ_SUCCESS) {
+	rc = 140; goto on_return;
+    }
+
+    /* Start streaming.. */
+    status = pjmedia_vid_port_start(renderer);
+    if (status != PJ_SUCCESS) {
+	rc = 150; goto on_return;
+    }
+    status = pjmedia_vid_port_start(capture);
+    if (status != PJ_SUCCESS) {
+	rc = 160; goto on_return;
+    }
+
+    /* Sleep while the webcam is being displayed... */
+    for (i = 0; i < LOOP_DURATION*10 && (!is_quitting); i++) {
+        pj_thread_sleep(100);
+    }
+
+on_return:
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(3, (THIS_FILE, status, "   error"));
+
+    if (capture)
+        pjmedia_vid_port_stop(capture);
+    if (renderer)
+        pjmedia_vid_port_stop(renderer);
+    if (capture)
+	pjmedia_vid_port_destroy(capture);
+    if (renderer) {
+        pjmedia_event_unsubscribe(NULL, &vid_event_cb, NULL, renderer);
+	pjmedia_vid_port_destroy(renderer);
+    }
+
+    pj_pool_release(pool);
+    return rc;
+}
+
+static int find_device(pjmedia_dir dir,
+		       pj_bool_t has_callback)
+{
+    unsigned i, count = pjmedia_vid_dev_count();
+ 
+    for (i = 0; i < count; ++i) {
+	pjmedia_vid_dev_info cdi;
+
+	if (pjmedia_vid_dev_get_info(i, &cdi) != PJ_SUCCESS)
+	    continue;
+	if ((cdi.dir & dir) != 0 && cdi.has_callback == has_callback)
+	    return i;
+    }
+    
+    return -999;
+}
+
+static int vidport_test(void)
+{
+    int i, j, k, l;
+    int cap_id, rend_id;
+    pjmedia_format_id test_fmts[] = {
+        PJMEDIA_FORMAT_RGBA,
+        PJMEDIA_FORMAT_I420
+    };
+
+    PJ_LOG(3, (THIS_FILE, " Video port tests:"));
+
+    /* Capturer's role: active/passive. */
+    for (i = 1; i >= 0; i--) {
+	/* Capturer's device has_callback: TRUE/FALSE. */
+	for (j = 1; j >= 0; j--) {
+	    cap_id = find_device(PJMEDIA_DIR_CAPTURE, j);
+	    if (cap_id < 0)
+		continue;
+
+	    /* Renderer's device has callback: TRUE/FALSE. */
+	    for (k = 1; k >= 0; k--) {
+		rend_id = find_device(PJMEDIA_DIR_RENDER, k);
+		if (rend_id < 0)
+		    continue;
+
+		/* Check various formats to test format conversion. */
+		for (l = 0; l < PJ_ARRAY_SIZE(test_fmts); ++l) {
+		    pjmedia_format fmt;
+
+		    PJ_LOG(3,(THIS_FILE,
+			      "capturer %s (stream: %s) ===> "
+			      "renderer %s (stream: %s)",
+			      (i? "active": "passive"),
+			      (j? "active": "passive"),
+			      (i? "passive": "active"),
+			      (k? "active": "passive")));
+
+		    pjmedia_format_init_video(&fmt, test_fmts[l],
+					      640, 480, 25, 1);
+		    capture_render_loopback(i, cap_id, rend_id, &fmt);
+		}
+	    }
+	}
+    }
+
+    return 0;
+}
+
+int vid_port_test(void)
+{
+    int rc = 0;
+    pj_status_t status;
+
+    status = pjmedia_vid_dev_subsys_init(mem);
+    if (status != PJ_SUCCESS)
+        return -10;
+
+    rc = vidport_test();
+    if (rc != 0)
+	goto on_return;
+
+on_return:
+    pjmedia_vid_dev_subsys_shutdown();
+
+    return rc;
+}
+
+
+#endif /* PJMEDIA_HAS_VIDEO */
diff --git a/jni/pjproject-android/.svn/pristine/05/0553654b5b65e8ec17ec825a44fd043f29530dcc.svn-base b/jni/pjproject-android/.svn/pristine/05/0553654b5b65e8ec17ec825a44fd043f29530dcc.svn-base
new file mode 100644
index 0000000..3ce877a
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/0553654b5b65e8ec17ec825a44fd043f29530dcc.svn-base
@@ -0,0 +1,1476 @@
+/* $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 
+ */
+#ifndef __PJ_OS_H__
+#define __PJ_OS_H__
+
+/**
+ * @file os.h
+ * @brief OS dependent functions
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_OS Operating System Dependent Functionality.
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_SYS_INFO System Information
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/**
+ * These enumeration contains constants to indicate support of miscellaneous
+ * system features. These will go in "flags" field of #pj_sys_info structure.
+ */
+typedef enum pj_sys_info_flag
+{
+    /**
+     * Support for Apple iOS background feature.
+     */
+    PJ_SYS_HAS_IOS_BG = 1
+
+} pj_sys_info_flag;
+
+
+/**
+ * This structure contains information about the system. Use #pj_get_sys_info()
+ * to obtain the system information.
+ */
+typedef struct pj_sys_info
+{
+    /**
+     * Null terminated string containing processor information (e.g. "i386",
+     * "x86_64"). It may contain empty string if the value cannot be obtained.
+     */
+    pj_str_t	machine;
+
+    /**
+     * Null terminated string identifying the system operation (e.g. "Linux",
+     * "win32", "wince"). It may contain empty string if the value cannot be
+     * obtained.
+     */
+    pj_str_t	os_name;
+
+    /**
+     * A number containing the operating system version number. By convention,
+     * this field is divided into four bytes, where the highest order byte
+     * contains the most major version of the OS, the next less significant
+     * byte contains the less major version, and so on. How the OS version
+     * number is mapped into these four bytes would be specific for each OS.
+     * For example, Linux-2.6.32-28 would yield "os_ver" value of 0x0206201c,
+     * while for Windows 7 it will be 0x06010000 (because dwMajorVersion is
+     * 6 and dwMinorVersion is 1 for Windows 7).
+     *
+     * This field may contain zero if the OS version cannot be obtained.
+     */
+    pj_uint32_t	os_ver;
+
+    /**
+     * Null terminated string identifying the SDK name that is used to build
+     * the library (e.g. "glibc", "uclibc", "msvc", "wince"). It may contain
+     * empty string if the value cannot eb obtained.
+     */
+    pj_str_t	sdk_name;
+
+    /**
+     * A number containing the SDK version, using the numbering convention as
+     * the "os_ver" field. The value will be zero if the version cannot be
+     * obtained.
+     */
+    pj_uint32_t	sdk_ver;
+
+    /**
+     * A longer null terminated string identifying the underlying system with
+     * as much information as possible.
+     */
+    pj_str_t	info;
+
+    /**
+     * Other flags containing system specific information. The value is
+     * bitmask of #pj_sys_info_flag constants.
+     */
+    pj_uint32_t	flags;
+
+} pj_sys_info;
+
+
+/**
+ * Obtain the system information.
+ *
+ * @return	System information structure.
+ */
+PJ_DECL(const pj_sys_info*) pj_get_sys_info(void);
+
+/*
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_THREAD Threads
+ * @ingroup PJ_OS
+ * @{
+ * This module provides multithreading API.
+ *
+ * \section pj_thread_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_thread_test
+ *  - \ref page_pjlib_sleep_test
+ *
+ */
+
+/**
+ * Thread creation flags:
+ * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
+ */
+typedef enum pj_thread_create_flags
+{
+    PJ_THREAD_SUSPENDED = 1
+} pj_thread_create_flags;
+
+
+/**
+ * Type of thread entry function.
+ */
+typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
+
+/**
+ * Size of thread struct.
+ */
+#if !defined(PJ_THREAD_DESC_SIZE)
+#   define PJ_THREAD_DESC_SIZE	    (64)
+#endif
+
+/**
+ * Thread structure, to thread's state when the thread is created by external
+ * or native API. 
+ */
+typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
+
+/**
+ * Get process ID.
+ * @return process ID.
+ */
+PJ_DECL(pj_uint32_t) pj_getpid(void);
+
+/**
+ * Create a new thread.
+ *
+ * @param pool          The memory pool from which the thread record 
+ *                      will be allocated from.
+ * @param thread_name   The optional name to be assigned to the thread.
+ * @param proc          Thread entry function.
+ * @param arg           Argument to be passed to the thread entry function.
+ * @param stack_size    The size of the stack for the new thread, or ZERO or
+ *                      PJ_THREAD_DEFAULT_STACK_SIZE to let the 
+ *		        library choose the reasonable size for the stack. 
+ *                      For some systems, the stack will be allocated from 
+ *                      the pool, so the pool must have suitable capacity.
+ * @param flags         Flags for thread creation, which is bitmask combination 
+ *                      from enum pj_thread_create_flags.
+ * @param thread        Pointer to hold the newly created thread.
+ *
+ * @return	        PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_create(  pj_pool_t *pool, 
+                                        const char *thread_name,
+				        pj_thread_proc *proc, 
+                                        void *arg,
+				        pj_size_t stack_size, 
+                                        unsigned flags,
+					pj_thread_t **thread );
+
+/**
+ * Register a thread that was created by external or native API to PJLIB.
+ * This function must be called in the context of the thread being registered.
+ * When the thread is created by external function or API call,
+ * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
+ * cooperate with PJLIB's framework. During registration, some data needs to
+ * be maintained, and this data must remain available during the thread's 
+ * lifetime.
+ *
+ * @param thread_name   The optional name to be assigned to the thread.
+ * @param desc          Thread descriptor, which must be available throughout 
+ *                      the lifetime of the thread.
+ * @param thread        Pointer to hold the created thread handle.
+ *
+ * @return              PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
+					  pj_thread_desc desc,
+					  pj_thread_t **thread);
+
+/**
+ * Check if this thread has been registered to PJLIB.
+ *
+ * @return		Non-zero if it is registered.
+ */
+PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
+
+
+/**
+ * Get thread priority value for the thread.
+ *
+ * @param thread	Thread handle.
+ *
+ * @return		Thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
+
+
+/**
+ * Set the thread priority. The priority value must be in the priority
+ * value range, which can be retrieved with #pj_thread_get_prio_min() and
+ * #pj_thread_get_prio_max() functions.
+ *
+ * @param thread	Thread handle.
+ * @param prio		New priority to be set to the thread.
+ *
+ * @return		PJ_SUCCESS on success or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio);
+
+/**
+ * Get the lowest priority value available for this thread.
+ *
+ * @param thread	Thread handle.
+ * @return		Minimum thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
+
+
+/**
+ * Get the highest priority value available for this thread.
+ *
+ * @param thread	Thread handle.
+ * @return		Minimum thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
+
+
+/**
+ * Return native handle from pj_thread_t for manipulation using native
+ * OS APIs.
+ *
+ * @param thread	PJLIB thread descriptor.
+ *
+ * @return		Native thread handle. For example, when the
+ *			backend thread uses pthread, this function will
+ *			return pointer to pthread_t, and on Windows,
+ *			this function will return HANDLE.
+ */
+PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
+
+/**
+ * Get thread name.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return Thread name as null terminated string.
+ */
+PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
+
+/**
+ * Resume a suspended thread.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
+
+/**
+ * Get the current thread.
+ *
+ * @return Thread handle of current thread.
+ */
+PJ_DECL(pj_thread_t*) pj_thread_this(void);
+
+/**
+ * Join thread, and block the caller thread until the specified thread exits.
+ * If the specified thread has already been dead, or it does not exist,
+ * the function will return immediately with successfull status.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
+
+
+/**
+ * Destroy thread and release resources allocated for the thread.
+ * However, the memory allocated for the pj_thread_t itself will only be released
+ * when the pool used to create the thread is destroyed.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
+
+
+/**
+ * Put the current thread to sleep for the specified miliseconds.
+ *
+ * @param msec Miliseconds delay.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
+
+/**
+ * @def PJ_CHECK_STACK()
+ * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
+ * The OS implementation may check that no stack overflow occurs, and
+ * it also may collect statistic about stack usage.
+ */
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+
+#  define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
+
+/** @internal
+ * The implementation of stack checking. 
+ */
+PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
+
+/** @internal
+ * Get maximum stack usage statistic. 
+ */
+PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
+
+/** @internal
+ * Dump thread stack status. 
+ */
+PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
+					      const char **file,
+					      int *line);
+#else
+
+#  define PJ_CHECK_STACK()
+/** pj_thread_get_stack_max_usage() for the thread */
+#  define pj_thread_get_stack_max_usage(thread)	    0
+/** pj_thread_get_stack_info() for the thread */
+#  define pj_thread_get_stack_info(thread,f,l)	    (*(f)="",*(l)=0)
+#endif	/* PJ_OS_HAS_CHECK_STACK */
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_SYMBIAN_OS Symbian OS Specific
+ * @ingroup PJ_OS
+ * @{
+ * Functionalities specific to Symbian OS.
+ *
+ * Symbian OS strongly discourages the use of polling since this wastes
+ * CPU power, and instead provides Active Object and Active Scheduler
+ * pattern to allow application (in this case, PJLIB) to register asynchronous
+ * tasks. PJLIB port for Symbian complies to this recommended behavior.
+ * As the result, few things have been changed in PJLIB for Symbian:
+ *	- the timer heap (see @ref PJ_TIMER) is implemented with active
+ *	  object framework, and each timer entry registered to the timer 
+ *	  heap will register an Active Object to the Active Scheduler.
+ *	  Because of this, polling the timer heap with pj_timer_heap_poll()
+ *	  is no longer necessary, and this function will just evaluate
+ *	  to nothing.
+ *	- the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
+ *	  active object framework, with each asynchronous operation will
+ *	  register an Active Object to the Active Scheduler. Because of
+ *	  this, polling the ioqueue with pj_ioqueue_poll() is no longer
+ *	  necessary, and this function will just evaluate to nothing.
+ *
+ * Since timer heap and ioqueue polling are no longer necessary, Symbian
+ * application can now poll for all events by calling 
+ * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
+ * PJLIB provides a thin wrapper which calls these two functions,
+ * called pj_symbianos_poll().
+ */
+ 
+/**
+ * Wait the completion of any Symbian active objects. When the timeout
+ * value is not specified (the \a ms_timeout argument is -1), this 
+ * function is a thin wrapper which calls \a User::WaitForAnyRequest() 
+ * and \a CActiveScheduler::RunIfReady(). If the timeout value is
+ * specified, this function will schedule a timer entry to the timer
+ * heap (which is an Active Object), to limit the wait time for event
+ * occurences. Scheduling a timer entry is an expensive operation,
+ * therefore application should only specify a timeout value when it's
+ * really necessary (for example, when it's not sure there are other
+ * Active Objects currently running in the application).
+ *
+ * @param priority	The minimum priority of the Active Objects to
+ *			poll, which values are from CActive::TPriority
+ *			constants. If -1 is given, CActive::EPriorityStandard.
+ *			priority will be used.
+ * @param ms_timeout	Optional timeout to wait. Application should
+ *			specify -1 to let the function wait indefinitely
+ *			for any events.
+ *
+ * @return		PJ_TRUE if there have been any events executed
+ *			during the polling. This function will only return
+ *			PJ_FALSE if \a ms_timeout argument is specified
+ *			(i.e. the value is not -1) and there was no event
+ *			executed when the timeout timer elapsed.
+ */
+PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
+
+
+/**
+ * This structure declares Symbian OS specific parameters that can be
+ * specified when calling #pj_symbianos_set_params().
+ */
+typedef struct pj_symbianos_params 
+{
+    /**
+     * Optional RSocketServ instance to be used by PJLIB. If this
+     * value is NULL, PJLIB will create a new RSocketServ instance
+     * when pj_init() is called.
+     */
+    void	*rsocketserv;
+    
+    /**
+     * Optional RConnection instance to be used by PJLIB when creating
+     * sockets. If this value is NULL, no RConnection will be
+     * specified when creating sockets.
+     */
+    void	*rconnection;
+    
+    /**
+     * Optional RHostResolver instance to be used by PJLIB. If this value
+     * is NULL, a new RHostResolver instance will be created when
+     * pj_init() is called.
+     */
+    void 	*rhostresolver;
+     
+    /**
+     * Optional RHostResolver for IPv6 instance to be used by PJLIB. 
+     * If this value is NULL, a new RHostResolver instance will be created
+     * when pj_init() is called.
+     */
+    void 	*rhostresolver6;
+     
+} pj_symbianos_params;
+
+/**
+ * Specify Symbian OS parameters to be used by PJLIB. This function MUST
+ * be called before #pj_init() is called.
+ *
+ * @param prm		Symbian specific parameters.
+ *
+ * @return		PJ_SUCCESS if the parameters can be applied
+ *			successfully.
+ */
+PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
+
+/**
+ *  Notify PJLIB that the access point connection has been down or unusable
+ *  and PJLIB should not try to access the Symbian socket API (especially ones
+ *  that send packets). Sending packet when RConnection is reconnected to 
+ *  different access point may cause the WaitForRequest() for the function to 
+ *  block indefinitely.
+ *  
+ *  @param up		If set to PJ_FALSE it will cause PJLIB to not try
+ *  			to access socket API, and error will be returned
+ *  			immediately instead.
+ */
+PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
+
+/**
+ * @}
+ */
+ 
+/* **************************************************************************/
+/**
+ * @defgroup PJ_TLS Thread Local Storage.
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/** 
+ * Allocate thread local storage index. The initial value of the variable at
+ * the index is zero.
+ *
+ * @param index	    Pointer to hold the return value.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
+
+/**
+ * Deallocate thread local variable.
+ *
+ * @param index	    The variable index.
+ */
+PJ_DECL(void) pj_thread_local_free(long index);
+
+/**
+ * Set the value of thread local variable.
+ *
+ * @param index	    The index of the variable.
+ * @param value	    The value.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
+
+/**
+ * Get the value of thread local variable.
+ *
+ * @param index	    The index of the variable.
+ * @return	    The value.
+ */
+PJ_DECL(void*) pj_thread_local_get(long index);
+
+
+/**
+ * @}
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_ATOMIC Atomic Variables
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides API to manipulate atomic variables.
+ *
+ * \section pj_atomic_examples_sec Examples
+ *
+ * For some example codes, please see:
+ *  - @ref page_pjlib_atomic_test
+ */
+
+
+/**
+ * Create atomic variable.
+ *
+ * @param pool	    The pool.
+ * @param initial   The initial value of the atomic variable.
+ * @param atomic    Pointer to hold the atomic variable upon return.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool, 
+				       pj_atomic_value_t initial,
+				       pj_atomic_t **atomic );
+
+/**
+ * Destroy atomic variable.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
+
+/**
+ * Set the value of an atomic type, and return the previous value.
+ *
+ * @param atomic_var	the atomic variable.
+ * @param value		value to be set to the variable.
+ */
+PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var, 
+			     pj_atomic_value_t value);
+
+/**
+ * Get the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return the value of the atomic variable.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type and get the result.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return              The incremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type and get the result.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return              The decremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Add a value to an atomic type.
+ *
+ * @param atomic_var	The atomic variable.
+ * @param value		Value to be added.
+ */
+PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
+			     pj_atomic_value_t value);
+
+/**
+ * Add a value to an atomic type and get the result.
+ *
+ * @param atomic_var	The atomic variable.
+ * @param value		Value to be added.
+ *
+ * @return              The result after the addition.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
+			                          pj_atomic_value_t value);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_MUTEX Mutexes.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * Mutex manipulation. Alternatively, application can use higher abstraction
+ * for lock objects, which provides uniform API for all kinds of lock 
+ * mechanisms, including mutex. See @ref PJ_LOCK for more information.
+ */
+
+/**
+ * Mutex types:
+ *  - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
+ *  - PJ_MUTEX_SIMPLE: non-recursive mutex.
+ *  - PJ_MUTEX_RECURSE: recursive mutex.
+ */
+typedef enum pj_mutex_type_e
+{
+    PJ_MUTEX_DEFAULT,
+    PJ_MUTEX_SIMPLE,
+    PJ_MUTEX_RECURSE
+} pj_mutex_type_e;
+
+
+/**
+ * Create mutex of the specified type.
+ *
+ * @param pool	    The pool.
+ * @param name	    Name to be associated with the mutex (for debugging).
+ * @param type	    The type of the mutex, of type #pj_mutex_type_e.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool, 
+                                     const char *name,
+				     int type, 
+                                     pj_mutex_t **mutex);
+
+/**
+ * Create simple, non-recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create 
+ * non-recursive mutex.
+ *
+ * @param pool	    The pool.
+ * @param name	    Mutex name.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
+					     pj_mutex_t **mutex );
+
+/**
+ * Create recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create 
+ * recursive mutex.
+ *
+ * @param pool	    The pool.
+ * @param name	    Mutex name.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
+					        const char *name,
+						pj_mutex_t **mutex );
+
+/**
+ * Acquire mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
+
+/**
+ * Release mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
+
+/**
+ * Try to acquire mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code if the
+ *		    lock couldn't be acquired.
+ */
+PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
+
+/**
+ * Destroy mutex.
+ *
+ * @param mutex	    Te mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
+
+/**
+ * Determine whether calling thread is owning the mutex (only available when
+ * PJ_DEBUG is set).
+ * @param mutex	    The mutex.
+ * @return	    Non-zero if yes.
+ */
+PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
+ * @ingroup PJ_OS
+ * @{
+ * Reader/writer mutex is a classic synchronization object where multiple
+ * readers can acquire the mutex, but only a single writer can acquire the 
+ * mutex.
+ */
+
+/**
+ * Opaque declaration for reader/writer mutex.
+ * Reader/writer mutex is a classic synchronization object where multiple
+ * readers can acquire the mutex, but only a single writer can acquire the 
+ * mutex.
+ */
+typedef struct pj_rwmutex_t pj_rwmutex_t;
+
+/**
+ * Create reader/writer mutex.
+ *
+ * @param pool	    Pool to allocate memory for the mutex.
+ * @param name	    Name to be assigned to the mutex.
+ * @param mutex	    Pointer to receive the newly created mutex.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
+				       pj_rwmutex_t **mutex);
+
+/**
+ * Lock the mutex for reading.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
+
+/**
+ * Lock the mutex for writing.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
+
+/**
+ * Release read lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
+
+/**
+ * Release write lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
+
+/**
+ * Destroy reader/writer mutex.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
+
+
+/**
+ * @}
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_CRIT_SEC Critical sections.
+ * @ingroup PJ_OS
+ * @{
+ * Critical section protection can be used to protect regions where:
+ *  - mutual exclusion protection is needed.
+ *  - it's rather too expensive to create a mutex.
+ *  - the time spent in the region is very very brief.
+ *
+ * Critical section is a global object, and it prevents any threads from
+ * entering any regions that are protected by critical section once a thread
+ * is already in the section.
+ *
+ * Critial section is \a not recursive!
+ *
+ * Application <b>MUST NOT</b> call any functions that may cause current
+ * thread to block (such as allocating memory, performing I/O, locking mutex,
+ * etc.) while holding the critical section.
+ */
+/**
+ * Enter critical section.
+ */
+PJ_DECL(void) pj_enter_critical_section(void);
+
+/**
+ * Leave critical section.
+ */
+PJ_DECL(void) pj_leave_critical_section(void);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+/**
+ * @defgroup PJ_SEM Semaphores.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction for semaphores, where available.
+ */
+
+/**
+ * Create semaphore.
+ *
+ * @param pool	    The pool.
+ * @param name	    Name to be assigned to the semaphore (for logging purpose)
+ * @param initial   The initial count of the semaphore.
+ * @param max	    The maximum count of the semaphore.
+ * @param sem	    Pointer to hold the semaphore created.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool, 
+                                    const char *name,
+				    unsigned initial, 
+                                    unsigned max,
+				    pj_sem_t **sem);
+
+/**
+ * Wait for semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
+
+/**
+ * Try wait for semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
+
+/**
+ * Release semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
+
+/**
+ * Destroy semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
+
+/**
+ * @}
+ */
+#endif	/* PJ_HAS_SEMAPHORE */
+
+
+/* **************************************************************************/
+#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
+/**
+ * @defgroup PJ_EVENT Event Object.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction to event object (e.g. Win32 Event) where
+ * available. Event objects can be used for synchronization among threads.
+ */
+
+/**
+ * Create event object.
+ *
+ * @param pool		The pool.
+ * @param name		The name of the event object (for logging purpose).
+ * @param manual_reset	Specify whether the event is manual-reset
+ * @param initial	Specify the initial state of the event object.
+ * @param event		Pointer to hold the returned event object.
+ *
+ * @return event handle, or NULL if failed.
+ */
+PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
+				     pj_bool_t manual_reset, pj_bool_t initial,
+				     pj_event_t **event);
+
+/**
+ * Wait for event to be signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
+
+/**
+ * Try wait for event object to be signalled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
+
+/**
+ * Set the event object state to signaled. For auto-reset event, this 
+ * will only release the first thread that are waiting on the event. For
+ * manual reset event, the state remains signaled until the event is reset.
+ * If there is no thread waiting on the event, the event object state 
+ * remains signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
+
+/**
+ * Set the event object to signaled state to release appropriate number of
+ * waiting threads and then reset the event object to non-signaled. For
+ * manual-reset event, this function will release all waiting threads. For
+ * auto-reset event, this function will only release one waiting thread.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
+
+/**
+ * Set the event object state to non-signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
+
+/**
+ * Destroy the event object.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
+
+/**
+ * @}
+ */
+#endif	/* PJ_HAS_EVENT_OBJ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJ_TIME Time Data Type and Manipulation.
+ * @ingroup PJ_OS
+ * @{
+ * This module provides API for manipulating time.
+ *
+ * \section pj_time_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_sleep_test
+ */
+
+/**
+ * Get current time of day in local representation.
+ *
+ * @param tv	Variable to store the result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
+
+
+/**
+ * Parse time value into date/time representation.
+ *
+ * @param tv	The time.
+ * @param pt	Variable to store the date time result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
+
+/**
+ * Encode date/time to time value.
+ *
+ * @param pt	The date/time.
+ * @param tv	Variable to store time value result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
+
+/**
+ * Convert local time to GMT.
+ *
+ * @param tv	Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
+
+/**
+ * Convert GMT to local time.
+ *
+ * @param tv	Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
+
+/**
+ * @defgroup PJ_TERM Terminal
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/**
+ * Set current terminal color.
+ *
+ * @param color	    The RGB color.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
+
+/**
+ * Get current terminal foreground color.
+ *
+ * @return RGB color.
+ */
+PJ_DECL(pj_color_t) pj_term_get_color(void);
+
+/**
+ * @}
+ */
+
+#endif	/* PJ_TERM_HAS_COLOR */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_TIMESTAMP High Resolution Timestamp
+ * @ingroup PJ_OS
+ * @{
+ *
+ * PJLIB provides <b>High Resolution Timestamp</b> API to access highest 
+ * resolution timestamp value provided by the platform. The API is usefull
+ * to measure precise elapsed time, and can be used in applications such
+ * as profiling.
+ *
+ * The timestamp value is represented in cycles, and can be related to
+ * normal time (in seconds or sub-seconds) using various functions provided.
+ *
+ * \section pj_timestamp_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_sleep_test
+ *  - \ref page_pjlib_timestamp_test
+ */
+
+/*
+ * High resolution timer.
+ */
+#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
+
+/**
+ * Get monotonic time since some unspecified starting point.
+ *
+ * @param tv	Variable to store the result.
+ *
+ * @return PJ_SUCCESS if successful.
+ */
+PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv);
+
+/**
+ * Acquire high resolution timer value. The time value are stored
+ * in cycles.
+ *
+ * @param ts	    High resolution timer value.
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ *
+ * @see pj_get_timestamp_freq().
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
+
+/**
+ * Get high resolution timer frequency, in cycles per second.
+ *
+ * @param freq	    Timer frequency, in cycles per second.
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
+
+/**
+ * Set timestamp from 32bit values.
+ * @param t	    The timestamp to be set.
+ * @param hi	    The high 32bit part.
+ * @param lo	    The low 32bit part.
+ */
+PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
+				   pj_uint32_t lo)
+{
+    t->u32.hi = hi;
+    t->u32.lo = lo;
+}
+
+
+/**
+ * Compare timestamp t1 and t2.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ * @return	    -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
+ */
+PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+    if (t1->u64 < t2->u64)
+	return -1;
+    else if (t1->u64 > t2->u64)
+	return 1;
+    else
+	return 0;
+#else
+    if (t1->u32.hi < t2->u32.hi ||
+	(t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
+	return -1;
+    else if (t1->u32.hi > t2->u32.hi ||
+	     (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
+	return 1;
+    else
+	return 0;
+#endif
+}
+
+
+/**
+ * Add timestamp t2 to t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 += t2->u64;
+#else
+    pj_uint32_t old = t1->u32.lo;
+    t1->u32.hi += t2->u32.hi;
+    t1->u32.lo += t2->u32.lo;
+    if (t1->u32.lo < old)
+	++t1->u32.hi;
+#endif
+}
+
+/**
+ * Add timestamp t2 to t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 += t2;
+#else
+    pj_uint32_t old = t1->u32.lo;
+    t1->u32.lo += t2;
+    if (t1->u32.lo < old)
+	++t1->u32.hi;
+#endif
+}
+
+/**
+ * Substract timestamp t2 from t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 -= t2->u64;
+#else
+    t1->u32.hi -= t2->u32.hi;
+    if (t1->u32.lo >= t2->u32.lo)
+	t1->u32.lo -= t2->u32.lo;
+    else {
+	t1->u32.lo -= t2->u32.lo;
+	--t1->u32.hi;
+    }
+#endif
+}
+
+/**
+ * Substract timestamp t2 from t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 -= t2;
+#else
+    if (t1->u32.lo >= t2)
+	t1->u32.lo -= t2;
+    else {
+	t1->u32.lo -= t2;
+	--t1->u32.hi;
+    }
+#endif
+}
+
+/**
+ * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
+ * and return a 32bit signed integer difference.
+ */
+PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
+					  const pj_timestamp *t2)
+{
+    /* Be careful with the signess (I think!) */
+#if PJ_HAS_INT64
+    pj_int64_t diff = t2->u64 - t1->u64;
+    return (pj_int32_t) diff;
+#else
+    pj_int32 diff = t2->u32.lo - t1->u32.lo;
+    return diff;
+#endif
+}
+
+
+/**
+ * Calculate the elapsed time, and store it in pj_time_val.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time as #pj_time_val.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
+                                      const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time as 32-bit miliseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in milisecond.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
+                                      const pj_timestamp *stop );
+
+/**
+ * Variant of #pj_elapsed_msec() which returns 64bit value.
+ */
+PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
+                                       const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit microseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in microsecond.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
+                                      const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit nanoseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in nanoseconds.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
+                                         const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit cycles.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in cycles.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
+                                       const pj_timestamp *stop );
+
+
+#endif	/* PJ_HAS_HIGH_RES_TIMER */
+
+/** @} */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_APP_OS Application execution
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/* Type for main function. */
+typedef int (*pj_main_func_ptr)(int argc, char *argv[]);
+
+/**
+ * Run the application. This function has to be called in the main thread
+ * and after doing the necessary initialization according to the flags
+ * provided, it will call main_func() function.
+ *
+ * @param main_func Application's main function.
+ * @param argc	    Number of arguments from the main() function, which
+ * 		    will be passed to main_func() function.
+ * @param argv	    The arguments from the main() function, which will
+ * 		    be passed to main_func() function.
+ * @param flags     Flags for application execution, currently must be 0.
+ *
+ * @return          main_func()'s return value.
+ */
+int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+	       unsigned flags);
+
+/** @} */
+
+
+/* **************************************************************************/
+/**
+ * Internal PJLIB function to initialize the threading subsystem.
+ * @return          PJ_SUCCESS or the appropriate error code.
+ */
+pj_status_t pj_thread_init(void);
+
+
+PJ_END_DECL
+
+#endif  /* __PJ_OS_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/05/058c7736b9468d82f98a908d3d3baee93a5a9d1c.svn-base b/jni/pjproject-android/.svn/pristine/05/058c7736b9468d82f98a908d3d3baee93a5a9d1c.svn-base
new file mode 100644
index 0000000..465c0e8
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/058c7736b9468d82f98a908d3d3baee93a5a9d1c.svn-base
@@ -0,0 +1,158 @@
+/* $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 
+ */
+#ifndef __PJMEDIA_VID_CODEC_UTIL_H__
+#define __PJMEDIA_VID_CODEC_UTIL_H__
+
+
+/**
+ * @file vid_codec_util.h
+ * @brief Video codec utilities.
+ */
+
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/sdp_neg.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Definition of H.263 parameters.
+ */
+typedef struct pjmedia_vid_codec_h263_fmtp
+{
+    unsigned mpi_cnt;		    /**< # of parsed MPI param		    */
+    struct mpi {
+	pjmedia_rect_size   size;   /**< Picture size/resolution	    */
+	unsigned	    val;    /**< MPI value			    */
+    } mpi[32];			    /**< Minimum Picture Interval parameter */
+
+} pjmedia_vid_codec_h263_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.263.
+ *
+ * @param fmtp		The H.263 SDP fmtp to be parsed.
+ * @param h263_fmtp	The parsing result.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_parse_fmtp(
+				const pjmedia_codec_fmtp *fmtp,
+				pjmedia_vid_codec_h263_fmtp *h263_fmtp);
+
+
+/**
+ * Parse, negotiate, and apply the encoding and decoding SDP fmtp of H.263
+ * in the specified codec parameter.
+ *
+ * @param param		The codec parameter.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(
+				pjmedia_vid_codec_param *param);
+
+
+/**
+ * Definition of H.264 parameters.
+ */
+typedef struct pjmedia_vid_codec_h264_fmtp
+{
+    /* profile-level-id */
+    pj_uint8_t	    profile_idc;    /**< Profile ID			    */
+    pj_uint8_t	    profile_iop;    /**< Profile constraints bits	    */
+    pj_uint8_t	    level;	    /**< Level				    */
+
+    /* packetization-mode */
+    pj_uint8_t	    packetization_mode;	/**< Packetization mode		    */
+
+    /* max-mbps, max-fs, max-cpb, max-dpb, and max-br */
+    unsigned	    max_mbps;	    /**< Max macroblock processing rate	    */
+    unsigned	    max_fs;	    /**< Max frame size (in macroblocks)    */
+    unsigned	    max_cpb;	    /**< Max coded picture buffer size	    */
+    unsigned	    max_dpb;	    /**< Max decoded picture buffer size    */
+    unsigned	    max_br;	    /**< Max video bit rate		    */
+
+    /* sprop-parameter-sets, in NAL units */
+    pj_size_t	    sprop_param_sets_len;   /**< Parameter set length	    */
+    pj_uint8_t	    sprop_param_sets[256];  /**< Parameter set (SPS & PPS),
+						 in NAL unit bitstream	    */
+
+} pjmedia_vid_codec_h264_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.264.
+ *
+ * @param fmtp		The H.264 SDP fmtp to be parsed.
+ * @param h264_fmtp	The parsing result.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(
+				const pjmedia_codec_fmtp *fmtp,
+				pjmedia_vid_codec_h264_fmtp *h264_fmtp);
+
+
+/**
+ * Match H.264 format in the SDP media offer and answer. This will compare
+ * H.264 identifier parameters in SDP fmtp, i.e: "profile-level-id" and
+ * "packetization-mode" fields. For better interoperability, when the option
+ * #PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER is set, this function
+ * may update the answer so the parameters in the answer match to ones
+ * in the offer.
+ *
+ * @param pool		The memory pool.
+ * @param offer		The SDP media offer.
+ * @param o_fmt_idx	Index of the H.264 format in the SDP media offer.
+ * @param answer	The SDP media answer.
+ * @param a_fmt_idx	Index of the H.264 format in the SDP media answer.
+ * @param option	The format matching option, see
+ *			#pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return		PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_match_sdp(
+						pj_pool_t *pool,
+						pjmedia_sdp_media *offer,
+						unsigned o_fmt_idx,
+						pjmedia_sdp_media *answer,
+						unsigned a_fmt_idx,
+						unsigned option);
+
+
+/**
+ * Parse and apply the encoding and decoding SDP fmtp of H.264 in the
+ * specified codec parameter. This will validate size and fps to conform
+ * to H.264 level specified in SDP fmtp "profile-level-id".
+ *
+ * @param param		The codec parameter.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(
+				pjmedia_vid_codec_param *param);
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJMEDIA_VID_CODEC_UTIL_H__ */
diff --git a/jni/pjproject-android/.svn/pristine/05/05e3d093260ca88f8e2afdec338efb23e09e1982.svn-base b/jni/pjproject-android/.svn/pristine/05/05e3d093260ca88f8e2afdec338efb23e09e1982.svn-base
new file mode 100644
index 0000000..634fb6a
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/05e3d093260ca88f8e2afdec338efb23e09e1982.svn-base
@@ -0,0 +1,7 @@
+#ifndef RESAMPLE_HAS_SMALL_FILTER
+#   define RESAMPLE_HAS_SMALL_FILTER	1
+#endif
+
+#ifndef RESAMPLE_HAS_LARGE_FILTER
+#   define RESAMPLE_HAS_LARGE_FILTER	1
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/05/05efcaea973f9b7650d0b67e3eaf326e837de395.svn-base b/jni/pjproject-android/.svn/pristine/05/05efcaea973f9b7650d0b67e3eaf326e837de395.svn-base
new file mode 100644
index 0000000..d9228c8
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/05/05efcaea973f9b7650d0b67e3eaf326e837de395.svn-base
@@ -0,0 +1,27 @@
+# $Id$
+import inc_sip as sip
+import inc_sdp as sdp
+
+sdp = \
+"""
+v=0
+o=- 0 0 IN IP4 127.0.0.1
+s=tester
+c=IN IP4 127.0.0.1
+t=0 0
+m=audio 4000 RTP/AVP 0 101
+a=rtpmap:0 PCMU/8000
+a=sendrecv
+a=rtpmap:101 telephone-event/8000
+a=fmtp:101 0-15
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:WnD7c1ksDGs+dIefCEo8omPg4uO8DYIinNGL5yxQ
+a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:t0r0/apkukU7JjjfR0mY8GEimBq4OiPEm9eKSFOx
+"""
+
+args = "--null-audio --auto-answer 200 --max-calls 1 --use-srtp 1 --srtp-secure 0"
+include = []
+exclude = []
+
+sendto_cfg = sip.SendtoCfg( "caller has used invalid crypto tag, callee must not accept the call", 
+			    pjsua_args=args, sdp=sdp, resp_code=406, 
+			    resp_inc=include, resp_exc=exclude)