summaryrefslogtreecommitdiffstats
path: root/voip
diff options
context:
space:
mode:
authorChia-chi Yeh <chiachi@android.com>2010-09-28 19:40:59 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-09-28 19:40:59 -0700
commite006e4d2c91c50795df0a02366b31610b4e97cb1 (patch)
tree9900718e21cd24be42972f50e1b349df03917ed9 /voip
parent3e94b94f56888acbd1f8deb23c05474baaf4fae3 (diff)
parenta6f950c9682ffffc00ca976aafeeedf391718b1d (diff)
downloadframeworks_base-e006e4d2c91c50795df0a02366b31610b4e97cb1.zip
frameworks_base-e006e4d2c91c50795df0a02366b31610b4e97cb1.tar.gz
frameworks_base-e006e4d2c91c50795df0a02366b31610b4e97cb1.tar.bz2
Merge changes Iae1913fb,I38dbefef into gingerbread
* changes: RTP: Enable GSM codec. RTP: Refactor out G711 codecs into another file.
Diffstat (limited to 'voip')
-rw-r--r--voip/java/android/net/rtp/AudioCodec.java2
-rw-r--r--voip/jni/rtp/Android.mk9
-rw-r--r--voip/jni/rtp/AudioCodec.cpp124
-rw-r--r--voip/jni/rtp/G711Codec.cpp138
-rw-r--r--voip/jni/rtp/GsmCodec.cpp74
5 files changed, 224 insertions, 123 deletions
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 class AudioCodec {
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 @@ LOCAL_SRC_FILES := \
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 @@ struct AudioCodecType {
} 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;
+}