Loading media/jni/Android.mk +6 −6 Original line number Diff line number Diff line Loading @@ -11,7 +11,8 @@ LOCAL_SRC_FILES:= \ android_media_MediaScanner.cpp \ android_media_MediaMetadataRetriever.cpp \ android_media_ResampleInputStream.cpp \ android_media_MediaProfiles.cpp android_media_MediaProfiles.cpp \ android_media_AmrInputStream.cpp LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ Loading @@ -27,12 +28,8 @@ LOCAL_SHARED_LIBRARIES := \ ifneq ($(BUILD_WITHOUT_PV),true) LOCAL_SRC_FILES += \ android_media_AmrInputStream.cpp LOCAL_SHARED_LIBRARIES += \ libopencore_player \ libomx_amrenc_sharedlibrary libopencore_player else LOCAL_CFLAGS += -DNO_OPENCORE endif Loading @@ -52,6 +49,9 @@ LOCAL_C_INCLUDES += \ external/tremor/Tremor \ frameworks/base/core/jni \ frameworks/base/media/libmedia \ frameworks/base/media/libstagefright/codecs/amrnb/enc/src \ frameworks/base/media/libstagefright/codecs/amrnb/common \ frameworks/base/media/libstagefright/codecs/amrnb/common/include \ $(PV_INCLUDES) \ $(JNI_H_INCLUDE) \ $(call include-path-for, corecg graphics) Loading media/jni/android_media_AmrInputStream.cpp +45 −70 Original line number Diff line number Diff line Loading @@ -18,36 +18,43 @@ #define LOG_TAG "AmrInputStream" #include "utils/Log.h" #include <media/mediarecorder.h> #include <stdio.h> #include <assert.h> #include <limits.h> #include <unistd.h> #include <fcntl.h> #include <utils/threads.h> #include "jni.h" #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include "gsmamr_encoder_wrapper.h" #include "gsmamr_enc.h" // ---------------------------------------------------------------------------- using namespace android; // Corresponds to max bit rate of 12.2 kbps. static const int aMaxOutputBufferSize = 32; static const int MAX_OUTPUT_BUFFER_SIZE = 32; static const int FRAME_DURATION_MS = 20; static const int SAMPLING_RATE_HZ = 8000; static const int SAMPLES_PER_FRAME = ((SAMPLING_RATE_HZ * FRAME_DURATION_MS) / 1000); static const int BYTES_PER_SAMPLE = 2; // Assume 16-bit PCM samples static const int BYTES_PER_FRAME = (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE); struct GsmAmrEncoderState { GsmAmrEncoderState() : mEncState(NULL), mSidState(NULL), mLastModeUsed(0) { } static const int SAMPLES_PER_FRAME = 8000 * 20 / 1000; ~GsmAmrEncoderState() {} void* mEncState; void* mSidState; int32_t mLastModeUsed; }; // // helper function to throw an exception // static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) { if (jclass cls = env->FindClass(ex)) { char msg[1000]; char msg[128]; sprintf(msg, fmt, data); env->ThrowNew(cls, msg); env->DeleteLocalRef(cls); Loading @@ -56,34 +63,21 @@ static void throwException(JNIEnv *env, const char* ex, const char* fmt, int dat static jint android_media_AmrInputStream_GsmAmrEncoderNew (JNIEnv *env, jclass clazz) { CPvGsmAmrEncoder* gae = new CPvGsmAmrEncoder(); GsmAmrEncoderState* gae = new GsmAmrEncoderState(); if (gae == NULL) { throwException(env, "java/lang/IllegalStateException", "new CPvGsmAmrEncoder() failed", 0); throwException(env, "java/lang/RuntimeException", "Out of memory", 0); } return (jint)gae; } static void android_media_AmrInputStream_GsmAmrEncoderInitialize (JNIEnv *env, jclass clazz, jint gae) { // set input parameters TEncodeProperties encodeProps; encodeProps.iInBitsPerSample = 16; encodeProps.iInSamplingRate = 8000; encodeProps.iInClockRate = 1000; encodeProps.iInNumChannels = 1; encodeProps.iInInterleaveMode = TEncodeProperties::EINTERLEAVE_LR; encodeProps.iMode = CPvGsmAmrEncoder::GSM_AMR_12_2; encodeProps.iBitStreamFormat = false; encodeProps.iAudioObjectType = 0; encodeProps.iOutSamplingRate = encodeProps.iInSamplingRate; encodeProps.iOutNumChannels = encodeProps.iInNumChannels; encodeProps.iOutClockRate = encodeProps.iInClockRate; if (int rtn = ((CPvGsmAmrEncoder*)gae)-> InitializeEncoder(aMaxOutputBufferSize, &encodeProps)) { GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false); if (nResult != OK) { throwException(env, "java/lang/IllegalArgumentException", "CPvGsmAmrEncoder::InitializeEncoder failed %d", rtn); "GsmAmrEncoder initialization failed %d", nResult); } } Loading @@ -91,42 +85,23 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode (JNIEnv *env, jclass clazz, jint gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) { // set up input stream jbyte inBuf[SAMPLES_PER_FRAME*2]; TInputAudioStream in; in.iSampleBuffer = (uint8*)inBuf; env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf); in.iSampleLength = sizeof(inBuf); in.iMode = CPvGsmAmrEncoder::GSM_AMR_12_2; in.iStartTime = 0; in.iStopTime = 0; // set up output stream jbyte outBuf[aMaxOutputBufferSize]; int32 sampleFrameSize[1] = { 0 }; TOutputAudioStream out; out.iBitStreamBuffer = (uint8*)outBuf; out.iNumSampleFrames = 0; out.iSampleFrameSize = sampleFrameSize; out.iStartTime = 0; out.iStopTime = 0; // encode if (int rtn = ((CPvGsmAmrEncoder*)gae)->Encode(in, out)) { throwException(env, "java/io/IOException", "CPvGsmAmrEncoder::Encode failed %d", rtn); return -1; } jbyte inBuf[BYTES_PER_FRAME]; jbyte outBuf[MAX_OUTPUT_BUFFER_SIZE]; // validate one-frame assumption if (out.iNumSampleFrames != 1) { env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf); GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; int32_t length = AMREncode(state->mEncState, state->mSidState, (Mode) MR122, (int16_t *) inBuf, (unsigned char *) outBuf, (Frame_Type_3GPP*) &state->mLastModeUsed, AMR_TX_WMF); if (length < 0) { throwException(env, "java/io/IOException", "CPvGsmAmrEncoder::Encode more than one frame returned %d", out.iNumSampleFrames); return 0; "Failed to encode a frame with error code: %d", length); return -1; } // copy result int length = out.iSampleFrameSize[0]; // The 1st byte of PV AMR frames are WMF (Wireless Multimedia Forum) // bitpacked, i.e.; // [P(4) + FT(4)]. Q=1 for good frame, P=padding bit, 0 Loading @@ -144,15 +119,15 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode static void android_media_AmrInputStream_GsmAmrEncoderCleanup (JNIEnv *env, jclass clazz, jint gae) { if (int rtn = ((CPvGsmAmrEncoder*)gae)->CleanupEncoder()) { throwException(env, "java/lang/IllegalStateException", "CPvGsmAmrEncoder::CleanupEncoder failed %d", rtn); } GsmAmrEncoderState *state = (GsmAmrEncoderState *)gae; AMREncodeExit(&state->mEncState, &state->mSidState); state->mEncState = NULL; state->mSidState = NULL; } static void android_media_AmrInputStream_GsmAmrEncoderDelete (JNIEnv *env, jclass clazz, jint gae) { delete (CPvGsmAmrEncoder*)gae; delete (GsmAmrEncoderState*)gae; } // ---------------------------------------------------------------------------- Loading Loading
media/jni/Android.mk +6 −6 Original line number Diff line number Diff line Loading @@ -11,7 +11,8 @@ LOCAL_SRC_FILES:= \ android_media_MediaScanner.cpp \ android_media_MediaMetadataRetriever.cpp \ android_media_ResampleInputStream.cpp \ android_media_MediaProfiles.cpp android_media_MediaProfiles.cpp \ android_media_AmrInputStream.cpp LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ Loading @@ -27,12 +28,8 @@ LOCAL_SHARED_LIBRARIES := \ ifneq ($(BUILD_WITHOUT_PV),true) LOCAL_SRC_FILES += \ android_media_AmrInputStream.cpp LOCAL_SHARED_LIBRARIES += \ libopencore_player \ libomx_amrenc_sharedlibrary libopencore_player else LOCAL_CFLAGS += -DNO_OPENCORE endif Loading @@ -52,6 +49,9 @@ LOCAL_C_INCLUDES += \ external/tremor/Tremor \ frameworks/base/core/jni \ frameworks/base/media/libmedia \ frameworks/base/media/libstagefright/codecs/amrnb/enc/src \ frameworks/base/media/libstagefright/codecs/amrnb/common \ frameworks/base/media/libstagefright/codecs/amrnb/common/include \ $(PV_INCLUDES) \ $(JNI_H_INCLUDE) \ $(call include-path-for, corecg graphics) Loading
media/jni/android_media_AmrInputStream.cpp +45 −70 Original line number Diff line number Diff line Loading @@ -18,36 +18,43 @@ #define LOG_TAG "AmrInputStream" #include "utils/Log.h" #include <media/mediarecorder.h> #include <stdio.h> #include <assert.h> #include <limits.h> #include <unistd.h> #include <fcntl.h> #include <utils/threads.h> #include "jni.h" #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include "gsmamr_encoder_wrapper.h" #include "gsmamr_enc.h" // ---------------------------------------------------------------------------- using namespace android; // Corresponds to max bit rate of 12.2 kbps. static const int aMaxOutputBufferSize = 32; static const int MAX_OUTPUT_BUFFER_SIZE = 32; static const int FRAME_DURATION_MS = 20; static const int SAMPLING_RATE_HZ = 8000; static const int SAMPLES_PER_FRAME = ((SAMPLING_RATE_HZ * FRAME_DURATION_MS) / 1000); static const int BYTES_PER_SAMPLE = 2; // Assume 16-bit PCM samples static const int BYTES_PER_FRAME = (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE); struct GsmAmrEncoderState { GsmAmrEncoderState() : mEncState(NULL), mSidState(NULL), mLastModeUsed(0) { } static const int SAMPLES_PER_FRAME = 8000 * 20 / 1000; ~GsmAmrEncoderState() {} void* mEncState; void* mSidState; int32_t mLastModeUsed; }; // // helper function to throw an exception // static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) { if (jclass cls = env->FindClass(ex)) { char msg[1000]; char msg[128]; sprintf(msg, fmt, data); env->ThrowNew(cls, msg); env->DeleteLocalRef(cls); Loading @@ -56,34 +63,21 @@ static void throwException(JNIEnv *env, const char* ex, const char* fmt, int dat static jint android_media_AmrInputStream_GsmAmrEncoderNew (JNIEnv *env, jclass clazz) { CPvGsmAmrEncoder* gae = new CPvGsmAmrEncoder(); GsmAmrEncoderState* gae = new GsmAmrEncoderState(); if (gae == NULL) { throwException(env, "java/lang/IllegalStateException", "new CPvGsmAmrEncoder() failed", 0); throwException(env, "java/lang/RuntimeException", "Out of memory", 0); } return (jint)gae; } static void android_media_AmrInputStream_GsmAmrEncoderInitialize (JNIEnv *env, jclass clazz, jint gae) { // set input parameters TEncodeProperties encodeProps; encodeProps.iInBitsPerSample = 16; encodeProps.iInSamplingRate = 8000; encodeProps.iInClockRate = 1000; encodeProps.iInNumChannels = 1; encodeProps.iInInterleaveMode = TEncodeProperties::EINTERLEAVE_LR; encodeProps.iMode = CPvGsmAmrEncoder::GSM_AMR_12_2; encodeProps.iBitStreamFormat = false; encodeProps.iAudioObjectType = 0; encodeProps.iOutSamplingRate = encodeProps.iInSamplingRate; encodeProps.iOutNumChannels = encodeProps.iInNumChannels; encodeProps.iOutClockRate = encodeProps.iInClockRate; if (int rtn = ((CPvGsmAmrEncoder*)gae)-> InitializeEncoder(aMaxOutputBufferSize, &encodeProps)) { GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false); if (nResult != OK) { throwException(env, "java/lang/IllegalArgumentException", "CPvGsmAmrEncoder::InitializeEncoder failed %d", rtn); "GsmAmrEncoder initialization failed %d", nResult); } } Loading @@ -91,42 +85,23 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode (JNIEnv *env, jclass clazz, jint gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) { // set up input stream jbyte inBuf[SAMPLES_PER_FRAME*2]; TInputAudioStream in; in.iSampleBuffer = (uint8*)inBuf; env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf); in.iSampleLength = sizeof(inBuf); in.iMode = CPvGsmAmrEncoder::GSM_AMR_12_2; in.iStartTime = 0; in.iStopTime = 0; // set up output stream jbyte outBuf[aMaxOutputBufferSize]; int32 sampleFrameSize[1] = { 0 }; TOutputAudioStream out; out.iBitStreamBuffer = (uint8*)outBuf; out.iNumSampleFrames = 0; out.iSampleFrameSize = sampleFrameSize; out.iStartTime = 0; out.iStopTime = 0; // encode if (int rtn = ((CPvGsmAmrEncoder*)gae)->Encode(in, out)) { throwException(env, "java/io/IOException", "CPvGsmAmrEncoder::Encode failed %d", rtn); return -1; } jbyte inBuf[BYTES_PER_FRAME]; jbyte outBuf[MAX_OUTPUT_BUFFER_SIZE]; // validate one-frame assumption if (out.iNumSampleFrames != 1) { env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf); GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; int32_t length = AMREncode(state->mEncState, state->mSidState, (Mode) MR122, (int16_t *) inBuf, (unsigned char *) outBuf, (Frame_Type_3GPP*) &state->mLastModeUsed, AMR_TX_WMF); if (length < 0) { throwException(env, "java/io/IOException", "CPvGsmAmrEncoder::Encode more than one frame returned %d", out.iNumSampleFrames); return 0; "Failed to encode a frame with error code: %d", length); return -1; } // copy result int length = out.iSampleFrameSize[0]; // The 1st byte of PV AMR frames are WMF (Wireless Multimedia Forum) // bitpacked, i.e.; // [P(4) + FT(4)]. Q=1 for good frame, P=padding bit, 0 Loading @@ -144,15 +119,15 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode static void android_media_AmrInputStream_GsmAmrEncoderCleanup (JNIEnv *env, jclass clazz, jint gae) { if (int rtn = ((CPvGsmAmrEncoder*)gae)->CleanupEncoder()) { throwException(env, "java/lang/IllegalStateException", "CPvGsmAmrEncoder::CleanupEncoder failed %d", rtn); } GsmAmrEncoderState *state = (GsmAmrEncoderState *)gae; AMREncodeExit(&state->mEncState, &state->mSidState); state->mEncState = NULL; state->mSidState = NULL; } static void android_media_AmrInputStream_GsmAmrEncoderDelete (JNIEnv *env, jclass clazz, jint gae) { delete (CPvGsmAmrEncoder*)gae; delete (GsmAmrEncoderState*)gae; } // ---------------------------------------------------------------------------- Loading