am 875500b4: Merge "AmrInputStream refresh: eliminate the dependency upon OpenCore\'s code" into gingerbread

Merge commit '875500b47ac74a164f7792ce89a16d600ea72695' into gingerbread-plus-aosp

* commit '875500b47ac74a164f7792ce89a16d600ea72695':
  AmrInputStream refresh: eliminate the dependency upon OpenCore's code
This commit is contained in:
James Dong
2010-06-21 17:37:15 -07:00
committed by Android Git Automerger
2 changed files with 51 additions and 76 deletions

View File

@@ -11,7 +11,8 @@ LOCAL_SRC_FILES:= \
android_media_MediaScanner.cpp \ android_media_MediaScanner.cpp \
android_media_MediaMetadataRetriever.cpp \ android_media_MediaMetadataRetriever.cpp \
android_media_ResampleInputStream.cpp \ android_media_ResampleInputStream.cpp \
android_media_MediaProfiles.cpp android_media_MediaProfiles.cpp \
android_media_AmrInputStream.cpp
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \ libandroid_runtime \
@@ -27,12 +28,8 @@ LOCAL_SHARED_LIBRARIES := \
ifneq ($(BUILD_WITHOUT_PV),true) ifneq ($(BUILD_WITHOUT_PV),true)
LOCAL_SRC_FILES += \
android_media_AmrInputStream.cpp
LOCAL_SHARED_LIBRARIES += \ LOCAL_SHARED_LIBRARIES += \
libopencore_player \ libopencore_player
libomx_amrenc_sharedlibrary
else else
LOCAL_CFLAGS += -DNO_OPENCORE LOCAL_CFLAGS += -DNO_OPENCORE
endif endif
@@ -52,6 +49,9 @@ LOCAL_C_INCLUDES += \
external/tremor/Tremor \ external/tremor/Tremor \
frameworks/base/core/jni \ frameworks/base/core/jni \
frameworks/base/media/libmedia \ 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) \ $(PV_INCLUDES) \
$(JNI_H_INCLUDE) \ $(JNI_H_INCLUDE) \
$(call include-path-for, corecg graphics) $(call include-path-for, corecg graphics)

View File

@@ -18,36 +18,43 @@
#define LOG_TAG "AmrInputStream" #define LOG_TAG "AmrInputStream"
#include "utils/Log.h" #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 "jni.h"
#include "JNIHelp.h" #include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h" #include "android_runtime/AndroidRuntime.h"
#include "gsmamr_encoder_wrapper.h" #include "gsmamr_enc.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
using namespace android; using namespace android;
// Corresponds to max bit rate of 12.2 kbps. // 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);
static const int SAMPLES_PER_FRAME = 8000 * 20 / 1000; struct GsmAmrEncoderState {
GsmAmrEncoderState()
: mEncState(NULL),
mSidState(NULL),
mLastModeUsed(0) {
}
~GsmAmrEncoderState() {}
void* mEncState;
void* mSidState;
int32_t mLastModeUsed;
};
// //
// helper function to throw an exception // helper function to throw an exception
// //
static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) { static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) {
if (jclass cls = env->FindClass(ex)) { if (jclass cls = env->FindClass(ex)) {
char msg[1000]; char msg[128];
sprintf(msg, fmt, data); sprintf(msg, fmt, data);
env->ThrowNew(cls, msg); env->ThrowNew(cls, msg);
env->DeleteLocalRef(cls); env->DeleteLocalRef(cls);
@@ -56,34 +63,21 @@ static void throwException(JNIEnv *env, const char* ex, const char* fmt, int dat
static jint android_media_AmrInputStream_GsmAmrEncoderNew static jint android_media_AmrInputStream_GsmAmrEncoderNew
(JNIEnv *env, jclass clazz) { (JNIEnv *env, jclass clazz) {
CPvGsmAmrEncoder* gae = new CPvGsmAmrEncoder(); GsmAmrEncoderState* gae = new GsmAmrEncoderState();
if (gae == NULL) { if (gae == NULL) {
throwException(env, "java/lang/IllegalStateException", throwException(env, "java/lang/RuntimeException",
"new CPvGsmAmrEncoder() failed", 0); "Out of memory", 0);
} }
return (jint)gae; return (jint)gae;
} }
static void android_media_AmrInputStream_GsmAmrEncoderInitialize static void android_media_AmrInputStream_GsmAmrEncoderInitialize
(JNIEnv *env, jclass clazz, jint gae) { (JNIEnv *env, jclass clazz, jint gae) {
// set input parameters GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
TEncodeProperties encodeProps; int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false);
encodeProps.iInBitsPerSample = 16; if (nResult != OK) {
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)) {
throwException(env, "java/lang/IllegalArgumentException", throwException(env, "java/lang/IllegalArgumentException",
"CPvGsmAmrEncoder::InitializeEncoder failed %d", rtn); "GsmAmrEncoder initialization failed %d", nResult);
} }
} }
@@ -91,42 +85,23 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode
(JNIEnv *env, jclass clazz, (JNIEnv *env, jclass clazz,
jint gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) { jint gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) {
// set up input stream jbyte inBuf[BYTES_PER_FRAME];
jbyte inBuf[SAMPLES_PER_FRAME*2]; jbyte outBuf[MAX_OUTPUT_BUFFER_SIZE];
TInputAudioStream in;
in.iSampleBuffer = (uint8*)inBuf;
env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf); env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf);
in.iSampleLength = sizeof(inBuf); GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
in.iMode = CPvGsmAmrEncoder::GSM_AMR_12_2; int32_t length = AMREncode(state->mEncState, state->mSidState,
in.iStartTime = 0; (Mode) MR122,
in.iStopTime = 0; (int16_t *) inBuf,
(unsigned char *) outBuf,
// set up output stream (Frame_Type_3GPP*) &state->mLastModeUsed,
jbyte outBuf[aMaxOutputBufferSize]; AMR_TX_WMF);
int32 sampleFrameSize[1] = { 0 }; if (length < 0) {
TOutputAudioStream out; throwException(env, "java/io/IOException",
out.iBitStreamBuffer = (uint8*)outBuf; "Failed to encode a frame with error code: %d", length);
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; return -1;
} }
// validate one-frame assumption
if (out.iNumSampleFrames != 1) {
throwException(env, "java/io/IOException",
"CPvGsmAmrEncoder::Encode more than one frame returned %d", out.iNumSampleFrames);
return 0;
}
// copy result
int length = out.iSampleFrameSize[0];
// The 1st byte of PV AMR frames are WMF (Wireless Multimedia Forum) // The 1st byte of PV AMR frames are WMF (Wireless Multimedia Forum)
// bitpacked, i.e.; // bitpacked, i.e.;
// [P(4) + FT(4)]. Q=1 for good frame, P=padding bit, 0 // [P(4) + FT(4)]. Q=1 for good frame, P=padding bit, 0
@@ -144,15 +119,15 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode
static void android_media_AmrInputStream_GsmAmrEncoderCleanup static void android_media_AmrInputStream_GsmAmrEncoderCleanup
(JNIEnv *env, jclass clazz, jint gae) { (JNIEnv *env, jclass clazz, jint gae) {
if (int rtn = ((CPvGsmAmrEncoder*)gae)->CleanupEncoder()) { GsmAmrEncoderState *state = (GsmAmrEncoderState *)gae;
throwException(env, "java/lang/IllegalStateException", AMREncodeExit(&state->mEncState, &state->mSidState);
"CPvGsmAmrEncoder::CleanupEncoder failed %d", rtn); state->mEncState = NULL;
} state->mSidState = NULL;
} }
static void android_media_AmrInputStream_GsmAmrEncoderDelete static void android_media_AmrInputStream_GsmAmrEncoderDelete
(JNIEnv *env, jclass clazz, jint gae) { (JNIEnv *env, jclass clazz, jint gae) {
delete (CPvGsmAmrEncoder*)gae; delete (GsmAmrEncoderState*)gae;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------