diff options
author | Chia-chi Yeh <chiachi@android.com> | 2010-09-28 19:40:59 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-09-28 19:40:59 -0700 |
commit | e006e4d2c91c50795df0a02366b31610b4e97cb1 (patch) | |
tree | 9900718e21cd24be42972f50e1b349df03917ed9 /voip | |
parent | 3e94b94f56888acbd1f8deb23c05474baaf4fae3 (diff) | |
parent | a6f950c9682ffffc00ca976aafeeedf391718b1d (diff) | |
download | frameworks_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.java | 2 | ||||
-rw-r--r-- | voip/jni/rtp/Android.mk | 9 | ||||
-rw-r--r-- | voip/jni/rtp/AudioCodec.cpp | 124 | ||||
-rw-r--r-- | voip/jni/rtp/G711Codec.cpp | 138 | ||||
-rw-r--r-- | voip/jni/rtp/GsmCodec.cpp | 74 |
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; +} |