am ebfe5632: am e006e4d2: Merge changes Iae1913fb,I38dbefef into gingerbread

Merge commit 'ebfe5632db275a89b49ab828064ba90db59702cf'

* commit 'ebfe5632db275a89b49ab828064ba90db59702cf':
  RTP: Enable GSM codec.
  RTP: Refactor out G711 codecs into another file.
diff --git a/voip/java/android/net/rtp/AudioCodec.java b/voip/java/android/net/rtp/AudioCodec.java
index 4851a46..dfa6841 100644
--- a/voip/java/android/net/rtp/AudioCodec.java
+++ b/voip/java/android/net/rtp/AudioCodec.java
@@ -81,7 +81,7 @@
     public static final AudioCodec AMR = new AudioCodec(97, "AMR/8000", null);
 
     // TODO: add rest of the codecs when the native part is done.
-    private static final AudioCodec[] sCodecs = {PCMU, PCMA};
+    private static final AudioCodec[] sCodecs = {GSM, PCMU, PCMA};
 
     private AudioCodec(int type, String rtpmap, String fmtp) {
         this.type = type;
diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk
index a364355..29683bd 100644
--- a/voip/jni/rtp/Android.mk
+++ b/voip/jni/rtp/Android.mk
@@ -26,16 +26,21 @@
 	util.cpp \
 	rtp_jni.cpp
 
+LOCAL_SRC_FILES += \
+	G711Codec.cpp \
+	GsmCodec.cpp
+
 LOCAL_SHARED_LIBRARIES := \
 	libnativehelper \
 	libcutils \
 	libutils \
 	libmedia
 
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_STATIC_LIBRARIES := libgsm
 
 LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE)
+	$(JNI_H_INCLUDE) \
+	external/libgsm/inc
 
 LOCAL_CFLAGS += -fvisibility=hidden
 
diff --git a/voip/jni/rtp/AudioCodec.cpp b/voip/jni/rtp/AudioCodec.cpp
index 4d8d36c..fc33ef2 100644
--- a/voip/jni/rtp/AudioCodec.cpp
+++ b/voip/jni/rtp/AudioCodec.cpp
@@ -18,124 +18,9 @@
 
 #include "AudioCodec.h"
 
-namespace {
-
-int8_t gExponents[128] = {
-    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-};
-
-//------------------------------------------------------------------------------
-
-class UlawCodec : public AudioCodec
-{
-public:
-    int set(int sampleRate, const char *fmtp) {
-        mSampleCount = sampleRate / 50;
-        return mSampleCount;
-    }
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, void *payload, int length);
-private:
-    int mSampleCount;
-};
-
-int UlawCodec::encode(void *payload, int16_t *samples)
-{
-    int8_t *ulaws = (int8_t *)payload;
-    for (int i = 0; i < mSampleCount; ++i) {
-        int sample = samples[i];
-        int sign = (sample >> 8) & 0x80;
-        if (sample < 0) {
-            sample = -sample;
-        }
-        sample += 132;
-        if (sample > 32767) {
-            sample = 32767;
-        }
-        int exponent = gExponents[sample >> 8];
-        int mantissa = (sample >> (exponent + 3)) & 0x0F;
-        ulaws[i] = ~(sign | (exponent << 4) | mantissa);
-    }
-    return mSampleCount;
-}
-
-int UlawCodec::decode(int16_t *samples, void *payload, int length)
-{
-    int8_t *ulaws = (int8_t *)payload;
-    for (int i = 0; i < length; ++i) {
-        int ulaw = ~ulaws[i];
-        int exponent = (ulaw >> 4) & 0x07;
-        int mantissa = ulaw & 0x0F;
-        int sample = (((mantissa << 3) + 132) << exponent) - 132;
-        samples[i] = (ulaw < 0 ? -sample : sample);
-    }
-    return length;
-}
-
-AudioCodec *newUlawCodec()
-{
-    return new UlawCodec;
-}
-
-//------------------------------------------------------------------------------
-
-class AlawCodec : public AudioCodec
-{
-public:
-    int set(int sampleRate, const char *fmtp) {
-        mSampleCount = sampleRate / 50;
-        return mSampleCount;
-    }
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, void *payload, int length);
-private:
-    int mSampleCount;
-};
-
-int AlawCodec::encode(void *payload, int16_t *samples)
-{
-    int8_t *alaws = (int8_t *)payload;
-    for (int i = 0; i < mSampleCount; ++i) {
-        int sample = samples[i];
-        int sign = (sample >> 8) & 0x80;
-        if (sample < 0) {
-            sample = -sample;
-        }
-        if (sample > 32767) {
-            sample = 32767;
-        }
-        int exponent = gExponents[sample >> 8];
-        int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
-        alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
-    }
-    return mSampleCount;
-}
-
-int AlawCodec::decode(int16_t *samples, void *payload, int length)
-{
-    int8_t *alaws = (int8_t *)payload;
-    for (int i = 0; i < length; ++i) {
-        int alaw = alaws[i] ^ 0x55;
-        int exponent = (alaw >> 4) & 0x07;
-        int mantissa = alaw & 0x0F;
-        int sample = (exponent == 0 ? (mantissa << 4) + 8 :
-            ((mantissa << 3) + 132) << exponent);
-        samples[i] = (alaw < 0 ? sample : -sample);
-    }
-    return length;
-}
-
-AudioCodec *newAlawCodec()
-{
-    return new AlawCodec;
-}
+extern AudioCodec *newAlawCodec();
+extern AudioCodec *newUlawCodec();
+extern AudioCodec *newGsmCodec();
 
 struct AudioCodecType {
     const char *name;
@@ -143,11 +28,10 @@
 } gAudioCodecTypes[] = {
     {"PCMA", newAlawCodec},
     {"PCMU", newUlawCodec},
+    {"GSM", newGsmCodec},
     {NULL, NULL},
 };
 
-} // namespace
-
 AudioCodec *newAudioCodec(const char *codecName)
 {
     AudioCodecType *type = gAudioCodecTypes;
diff --git a/voip/jni/rtp/G711Codec.cpp b/voip/jni/rtp/G711Codec.cpp
new file mode 100644
index 0000000..091afa9
--- /dev/null
+++ b/voip/jni/rtp/G711Codec.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyrightm (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioCodec.h"
+
+namespace {
+
+int8_t gExponents[128] = {
+    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+//------------------------------------------------------------------------------
+
+class UlawCodec : public AudioCodec
+{
+public:
+    int set(int sampleRate, const char *fmtp) {
+        mSampleCount = sampleRate / 50;
+        return mSampleCount;
+    }
+    int encode(void *payload, int16_t *samples);
+    int decode(int16_t *samples, void *payload, int length);
+private:
+    int mSampleCount;
+};
+
+int UlawCodec::encode(void *payload, int16_t *samples)
+{
+    int8_t *ulaws = (int8_t *)payload;
+    for (int i = 0; i < mSampleCount; ++i) {
+        int sample = samples[i];
+        int sign = (sample >> 8) & 0x80;
+        if (sample < 0) {
+            sample = -sample;
+        }
+        sample += 132;
+        if (sample > 32767) {
+            sample = 32767;
+        }
+        int exponent = gExponents[sample >> 8];
+        int mantissa = (sample >> (exponent + 3)) & 0x0F;
+        ulaws[i] = ~(sign | (exponent << 4) | mantissa);
+    }
+    return mSampleCount;
+}
+
+int UlawCodec::decode(int16_t *samples, void *payload, int length)
+{
+    int8_t *ulaws = (int8_t *)payload;
+    for (int i = 0; i < length; ++i) {
+        int ulaw = ~ulaws[i];
+        int exponent = (ulaw >> 4) & 0x07;
+        int mantissa = ulaw & 0x0F;
+        int sample = (((mantissa << 3) + 132) << exponent) - 132;
+        samples[i] = (ulaw < 0 ? -sample : sample);
+    }
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+class AlawCodec : public AudioCodec
+{
+public:
+    int set(int sampleRate, const char *fmtp) {
+        mSampleCount = sampleRate / 50;
+        return mSampleCount;
+    }
+    int encode(void *payload, int16_t *samples);
+    int decode(int16_t *samples, void *payload, int length);
+private:
+    int mSampleCount;
+};
+
+int AlawCodec::encode(void *payload, int16_t *samples)
+{
+    int8_t *alaws = (int8_t *)payload;
+    for (int i = 0; i < mSampleCount; ++i) {
+        int sample = samples[i];
+        int sign = (sample >> 8) & 0x80;
+        if (sample < 0) {
+            sample = -sample;
+        }
+        if (sample > 32767) {
+            sample = 32767;
+        }
+        int exponent = gExponents[sample >> 8];
+        int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
+        alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
+    }
+    return mSampleCount;
+}
+
+int AlawCodec::decode(int16_t *samples, void *payload, int length)
+{
+    int8_t *alaws = (int8_t *)payload;
+    for (int i = 0; i < length; ++i) {
+        int alaw = alaws[i] ^ 0x55;
+        int exponent = (alaw >> 4) & 0x07;
+        int mantissa = alaw & 0x0F;
+        int sample = (exponent == 0 ? (mantissa << 4) + 8 :
+            ((mantissa << 3) + 132) << exponent);
+        samples[i] = (alaw < 0 ? sample : -sample);
+    }
+    return length;
+}
+
+} // namespace
+
+AudioCodec *newUlawCodec()
+{
+    return new UlawCodec;
+}
+
+AudioCodec *newAlawCodec()
+{
+    return new AlawCodec;
+}
diff --git a/voip/jni/rtp/GsmCodec.cpp b/voip/jni/rtp/GsmCodec.cpp
new file mode 100644
index 0000000..8d2286e
--- /dev/null
+++ b/voip/jni/rtp/GsmCodec.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyrightm (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioCodec.h"
+
+extern "C" {
+#include "gsm.h"
+}
+
+namespace {
+
+class GsmCodec : public AudioCodec
+{
+public:
+    GsmCodec() {
+        mEncode = gsm_create();
+        mDecode = gsm_create();
+    }
+
+    ~GsmCodec() {
+        if (mEncode) {
+            gsm_destroy(mEncode);
+        }
+        if (mDecode) {
+            gsm_destroy(mDecode);
+        }
+    }
+
+    int set(int sampleRate, const char *fmtp) {
+        return (sampleRate == 8000 && mEncode && mDecode) ? 160 : -1;
+    }
+
+    int encode(void *payload, int16_t *samples);
+    int decode(int16_t *samples, void *payload, int length);
+
+private:
+    gsm mEncode;
+    gsm mDecode;
+};
+
+int GsmCodec::encode(void *payload, int16_t *samples)
+{
+    gsm_encode(mEncode, samples, (unsigned char *)payload);
+    return 33;
+}
+
+int GsmCodec::decode(int16_t *samples, void *payload, int length)
+{
+    if (length == 33 &&
+        gsm_decode(mDecode, (unsigned char *)payload, samples) == 0) {
+        return 160;
+    }
+    return -1;
+}
+
+} // namespace
+
+AudioCodec *newGsmCodec()
+{
+    return new GsmCodec;
+}