-Adding small performance tweaks
parent
d79ffdd352
commit
df94ad0c48
|
@ -13,6 +13,8 @@ to end. */
|
|||
#define PREMATURE_END_OF_FILE -26
|
||||
#define SUCCESS 0
|
||||
|
||||
#define BUFFER_LENGTH 4096
|
||||
|
||||
extern void _VDBG_dump(void);
|
||||
|
||||
//Stops the vorbis data feed
|
||||
|
@ -40,48 +42,39 @@ void throwDecodeException(JNIEnv *env, const int code, jobject* vorbisDataFeed,
|
|||
}
|
||||
|
||||
//Reads raw vorbis data from the jni callback
|
||||
int readVorbisDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* readVorbisDataMethodId, char* buffer, int length) {
|
||||
int readVorbisDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* readVorbisDataMethodId, char* buffer, jbyteArray* jByteArrayReadBuffer) {
|
||||
//Call the read method
|
||||
int readByteCount = (*env)->CallIntMethod(env, (*vorbisDataFeed), (*readVorbisDataMethodId), (*jByteArrayReadBuffer), BUFFER_LENGTH);
|
||||
|
||||
//create a new java byte array to pass to the vorbis data feed method
|
||||
jbyteArray jByteArray = (*env)->NewByteArray(env, length);
|
||||
int readByteCount = (*env)->CallIntMethod(env, (*vorbisDataFeed), (*readVorbisDataMethodId), jByteArray, length);
|
||||
|
||||
//Don't bother copying, just delete the reference and return 0
|
||||
//Don't bother copying, just return 0
|
||||
if(readByteCount == 0) {
|
||||
(*env)->DeleteLocalRef(env, jByteArray);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Gets the bytes from the java array and copies them to the vorbis buffer
|
||||
jbyte* readBytes = (*env)->GetByteArrayElements(env, jByteArray, NULL);
|
||||
jbyte* readBytes = (*env)->GetByteArrayElements(env, (*jByteArrayReadBuffer), NULL);
|
||||
memcpy(buffer, readBytes, readByteCount);
|
||||
|
||||
//Clean up memory and return how much data was read
|
||||
(*env)->ReleaseByteArrayElements(env, jByteArray, readBytes, JNI_ABORT);
|
||||
(*env)->DeleteLocalRef(env, jByteArray);
|
||||
(*env)->ReleaseByteArrayElements(env, (*jByteArrayReadBuffer), readBytes, JNI_ABORT);
|
||||
|
||||
//Return the amount actually read
|
||||
return readByteCount;
|
||||
|
||||
}
|
||||
|
||||
//Writes the pcm data to the Java layer
|
||||
void writePCMDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* writePCMDataMethodId, ogg_int16_t* buffer, int bytes) {
|
||||
void writePCMDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* writePCMDataMethodId, ogg_int16_t* buffer, int bytes, jshortArray* jShortArrayWriteBuffer) {
|
||||
|
||||
//No data to read, just exit
|
||||
if(bytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Create and copy the contents of what we're writing to the java short array
|
||||
jshortArray jShortArray = (*env)->NewShortArray(env, bytes);
|
||||
(*env)->SetShortArrayRegion(env, jShortArray, 0, bytes, (jshort *)buffer);
|
||||
//Copy the contents of what we're writing to the java short array
|
||||
(*env)->SetShortArrayRegion(env, (*jShortArrayWriteBuffer), 0, bytes, (jshort *)buffer);
|
||||
|
||||
//Call the write pcm data method
|
||||
(*env)->CallVoidMethod(env, (*vorbisDataFeed), (*writePCMDataMethodId), jShortArray, bytes);
|
||||
|
||||
//cleanup
|
||||
(*env)->DeleteLocalRef(env, jShortArray);
|
||||
|
||||
(*env)->CallVoidMethod(env, (*vorbisDataFeed), (*writePCMDataMethodId), (*jShortArrayWriteBuffer), bytes);
|
||||
}
|
||||
|
||||
//Starts the decode feed with the necessary information about sample rates, channels, etc about the stream
|
||||
|
@ -119,6 +112,12 @@ void startReadingHeader(JNIEnv *env, jobject *vorbisDataFeed, jmethodID* startRe
|
|||
JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
||||
(JNIEnv *env, jclass cls, jobject vorbisDataFeed) {
|
||||
|
||||
//Create a new java byte array to pass to the vorbis data feed method
|
||||
jbyteArray jByteArrayReadBuffer = (*env)->NewByteArray(env, BUFFER_LENGTH);
|
||||
|
||||
//Create our write buffer
|
||||
jshortArray jShortArrayWriteBuffer = (*env)->NewShortArray(env, BUFFER_LENGTH*2);
|
||||
|
||||
//Find our java classes we'll be calling
|
||||
jclass vorbisDataFeedClass = (*env)->FindClass(env, "org/xiph/vorbis/decoder/DecodeFeed");
|
||||
|
||||
|
@ -129,8 +128,8 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
jmethodID startReadingHeaderMethodId = (*env)->GetMethodID(env, vorbisDataFeedClass, "startReadingHeader", "()V");
|
||||
jmethodID stopMethodId = (*env)->GetMethodID(env, vorbisDataFeedClass, "stop", "()V");
|
||||
|
||||
ogg_int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
|
||||
int convsize=4096;
|
||||
ogg_int16_t convbuffer[BUFFER_LENGTH]; /* take 8k out of the data segment, not the stack */
|
||||
int convsize=BUFFER_LENGTH;
|
||||
|
||||
ogg_sync_state oy; /* sync and verify incoming physical bitstream */
|
||||
ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
|
||||
|
@ -164,15 +163,15 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
|
||||
/* submit a 4k block to libvorbis' Ogg layer */
|
||||
__android_log_print(ANDROID_LOG_INFO, "VorbisDecoder", "Submitting 4k block to libvorbis' Ogg layer");
|
||||
buffer=ogg_sync_buffer(&oy,4096);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, 4096);
|
||||
buffer=ogg_sync_buffer(&oy,BUFFER_LENGTH);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, &jByteArrayReadBuffer);
|
||||
ogg_sync_wrote(&oy,bytes);
|
||||
|
||||
/* Get the first page. */
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "VorbisDecoder", "Getting the first page, read (%d) bytes", bytes);
|
||||
if(ogg_sync_pageout(&oy,&og)!=1){
|
||||
/* have we simply run out of data? If so, we're done. */
|
||||
if(bytes<4096)break;
|
||||
if(bytes<BUFFER_LENGTH)break;
|
||||
|
||||
/* error case. Must not be Vorbis data */
|
||||
throwDecodeException(env, INVALID_OGG_BITSTREAM, &vorbisDataFeed, &stopMethodId);
|
||||
|
@ -256,8 +255,8 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
}
|
||||
}
|
||||
/* no harm in not checking before adding more */
|
||||
buffer=ogg_sync_buffer(&oy,4096);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, 4096);
|
||||
buffer=ogg_sync_buffer(&oy,BUFFER_LENGTH);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, &jByteArrayReadBuffer);
|
||||
if(bytes==0 && i<2){
|
||||
throwDecodeException(env, PREMATURE_END_OF_FILE, &vorbisDataFeed, &stopMethodId);
|
||||
return PREMATURE_END_OF_FILE;
|
||||
|
@ -281,7 +280,7 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
start(env, &vorbisDataFeed, &startMethodId, vi.rate, vi.channels, vc.vendor);
|
||||
}
|
||||
|
||||
convsize=4096/vi.channels;
|
||||
convsize=BUFFER_LENGTH/vi.channels;
|
||||
|
||||
/* OK, got and parsed all three headers. Initialize the Vorbis
|
||||
packet->PCM decoder. */
|
||||
|
@ -365,7 +364,7 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
__android_log_print(ANDROID_LOG_INFO, "VorbisDecoder", "Clipping in frame %ld\n",(long)(vd.sequence));
|
||||
}
|
||||
|
||||
writePCMDataFromVorbisDataFeed(env, &vorbisDataFeed, &writePCMDataMethodId, &convbuffer[0], bout*vi.channels);
|
||||
writePCMDataFromVorbisDataFeed(env, &vorbisDataFeed, &writePCMDataMethodId, &convbuffer[0], bout*vi.channels, &jShortArrayWriteBuffer);
|
||||
|
||||
vorbis_synthesis_read(&vd,bout); /* tell libvorbis how many samples we actually consumed */
|
||||
}
|
||||
|
@ -376,8 +375,8 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
}
|
||||
|
||||
if(!eos){
|
||||
buffer=ogg_sync_buffer(&oy,4096);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, 4096);
|
||||
buffer=ogg_sync_buffer(&oy,BUFFER_LENGTH);
|
||||
bytes=readVorbisDataFromVorbisDataFeed(env, &vorbisDataFeed, &readVorbisDataMethodId, buffer, &jByteArrayReadBuffer);
|
||||
ogg_sync_wrote(&oy,bytes);
|
||||
if(bytes==0) {
|
||||
eos=1;
|
||||
|
@ -406,6 +405,13 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_decoder_VorbisDecoder_startDecoding
|
|||
/* OK, clean up the framer */
|
||||
ogg_sync_clear(&oy);
|
||||
|
||||
|
||||
|
||||
stopDecodeFeed(env, &vorbisDataFeed, &stopMethodId);
|
||||
|
||||
//Clean up our buffers
|
||||
(*env)->DeleteLocalRef(env, jByteArrayReadBuffer);
|
||||
(*env)->DeleteLocalRef(env, jShortArrayWriteBuffer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
|
@ -23,10 +23,10 @@ void stopDecodeFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* stopMethodI
|
|||
void throwDecodeException(JNIEnv *env, const int code, jobject* vorbisDataFeed, jmethodID* stopMethodId);
|
||||
|
||||
//Reads raw vorbis data from the jni callback
|
||||
int readVorbisDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* readVorbisDataMethodId, char* buffer, int length);
|
||||
int readVorbisDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* readVorbisDataMethodId, char* buffer, jbyteArray* jByteArrayReadBuffer);
|
||||
|
||||
//Writes the pcm data to the Java layer
|
||||
void writePCMDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* writePCMDataMethodId, ogg_int16_t* buffer, int bytes);
|
||||
void writePCMDataFromVorbisDataFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* writePCMDataMethodId, ogg_int16_t* buffer, int bytes, jshortArray* jShortArrayWriteBuffer);
|
||||
|
||||
//Starts the decode feed with the necessary information about sample rates, channels, etc about the stream
|
||||
void start(JNIEnv *env, jobject *vorbisDataFeed, jmethodID* startMethodId, long sampleRate, long channels, char* vendor);
|
||||
|
|
|
@ -40,31 +40,27 @@ void stopEncodeFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* stopMethodI
|
|||
}
|
||||
|
||||
//Reads pcm data from the jni callback
|
||||
long readPCMDataFromEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* readPCMDataMethodId, char* buffer, int length) {
|
||||
|
||||
//create a new java byte array to pass to the data feed method
|
||||
jbyteArray jByteArray = (*env)->NewByteArray(env, length);
|
||||
long readByteCount = (*env)->CallLongMethod(env, (*encoderDataFeed), (*readPCMDataMethodId), jByteArray, length);
|
||||
long readPCMDataFromEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* readPCMDataMethodId, char* buffer, int length, jbyteArray* jByteArrayBuffer) {
|
||||
long readByteCount = (*env)->CallLongMethod(env, (*encoderDataFeed), (*readPCMDataMethodId), (*jByteArrayBuffer), length);
|
||||
|
||||
//Don't bother copying, just delete the reference and return 0
|
||||
if(readByteCount == 0) {
|
||||
(*env)->DeleteLocalRef(env, jByteArray);
|
||||
(*env)->DeleteLocalRef(env, (*jByteArrayBuffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Gets the bytes from the java array and copies them to the pcm buffer
|
||||
jbyte* readBytes = (*env)->GetByteArrayElements(env, jByteArray, NULL);
|
||||
jbyte* readBytes = (*env)->GetByteArrayElements(env, (*jByteArrayBuffer), NULL);
|
||||
memcpy(buffer, readBytes, readByteCount);
|
||||
|
||||
//Clean up memory and return how much data was read
|
||||
(*env)->ReleaseByteArrayElements(env, jByteArray, readBytes, JNI_ABORT);
|
||||
(*env)->DeleteLocalRef(env, jByteArray);
|
||||
(*env)->ReleaseByteArrayElements(env, (*jByteArrayBuffer), readBytes, JNI_ABORT);
|
||||
|
||||
return readByteCount;
|
||||
}
|
||||
|
||||
//Writes the vorbis data to the Java layer
|
||||
int writeVorbisDataToEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* writeVorbisDataMethodId, char* buffer, int bytes) {
|
||||
int writeVorbisDataToEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* writeVorbisDataMethodId, char* buffer, int bytes, jbyteArray* jByteArrayWriteBuffer) {
|
||||
|
||||
//No data to write, just exit
|
||||
if(bytes == 0) {
|
||||
|
@ -73,14 +69,12 @@ int writeVorbisDataToEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmet
|
|||
|
||||
//Create and copy the contents of what we're writing to the java byte array
|
||||
jbyteArray jByteArray = (*env)->NewByteArray(env, bytes);
|
||||
(*env)->SetByteArrayRegion(env, jByteArray, 0, bytes, (jbyte *)buffer);
|
||||
(*env)->SetByteArrayRegion(env, (*jByteArrayWriteBuffer), 0, bytes, (jbyte *)buffer);
|
||||
|
||||
//Call the write vorbis data method
|
||||
int amountWritten = (*env)->CallIntMethod(env, (*encoderDataFeed), (*writeVorbisDataMethodId), jByteArray, bytes);
|
||||
|
||||
//cleanup
|
||||
(*env)->DeleteLocalRef(env, jByteArray);
|
||||
int amountWritten = (*env)->CallIntMethod(env, (*encoderDataFeed), (*writeVorbisDataMethodId), (*jByteArrayWriteBuffer), bytes);
|
||||
|
||||
//Return the amount that was actually written
|
||||
return amountWritten;
|
||||
}
|
||||
|
||||
|
@ -90,6 +84,12 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
|||
//Create our PCM data buffer
|
||||
signed char readbuffer[READ*4+44];
|
||||
|
||||
//Create a new java byte array to pass to the data feed method
|
||||
jbyteArray jByteArrayBuffer = (*env)->NewByteArray(env, READ*4);
|
||||
|
||||
//Create a new java byte buffer to write to
|
||||
jbyteArray jByteArrayWriteBuffer = (*env)->NewByteArray(env, READ*8);
|
||||
|
||||
//Find our java classes we'll be calling
|
||||
jclass encoderDataFeedClass = (*env)->FindClass(env, "org/xiph/vorbis/encoder/EncodeFeed");
|
||||
|
||||
|
@ -201,8 +201,8 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
|||
while(!eos){
|
||||
int result=ogg_stream_flush(&os,&og);
|
||||
if(result==0)break;
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.header, og.header_len);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.body, og.body_len);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.header, og.header_len, &jByteArrayWriteBuffer);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.body, og.body_len, &jByteArrayWriteBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
|||
__android_log_print(ANDROID_LOG_INFO, "VorbisEncoder", "Starting to read from pcm callback");
|
||||
while(!eos){
|
||||
long i;
|
||||
long bytes = readPCMDataFromEncoderDataFeed(env, &encoderDataFeed, &readPCMDataMethodId, readbuffer, READ*4);
|
||||
long bytes = readPCMDataFromEncoderDataFeed(env, &encoderDataFeed, &readPCMDataMethodId, readbuffer, READ*4, &jByteArrayBuffer);
|
||||
|
||||
if(bytes==0){
|
||||
/* end of file. this can be done implicitly in the mainline,
|
||||
|
@ -257,8 +257,8 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
|||
while(!eos){
|
||||
int result=ogg_stream_pageout(&os,&og);
|
||||
if(result==0)break;
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.header, og.header_len);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.body, og.body_len);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.header, og.header_len, &jByteArrayWriteBuffer);
|
||||
writeVorbisDataToEncoderDataFeed(env, &encoderDataFeed, &writeVorbisDataMethodId, og.body, og.body_len, &jByteArrayWriteBuffer);
|
||||
|
||||
/* this could be set above, but for illustrative purposes, I do
|
||||
it here (to show that vorbis does know where the stream ends) */
|
||||
|
@ -281,5 +281,10 @@ JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
|||
libvorbis. They're never freed or manipulated directly */
|
||||
__android_log_print(ANDROID_LOG_INFO, "VorbisEncoder", "Completed encoding.");
|
||||
stopEncodeFeed(env, &encoderDataFeed, &stopMethodId);
|
||||
|
||||
//Clean up encode buffers
|
||||
(*env)->DeleteLocalRef(env, jByteArrayBuffer);
|
||||
(*env)->DeleteLocalRef(env, jByteArrayWriteBuffer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ void startEncodeFeed(JNIEnv *env, jobject *vorbisDataFeed, jmethodID* startMetho
|
|||
void stopEncodeFeed(JNIEnv *env, jobject* vorbisDataFeed, jmethodID* stopMethodId);
|
||||
|
||||
//Reads pcm data from the jni callback
|
||||
long readPCMDataFromEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* readPCMDataMethodId, char* buffer, int length);
|
||||
long readPCMDataFromEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* readPCMDataMethodId, char* buffer, int length, jbyteArray* jByteArrayBuffer);
|
||||
|
||||
//Writes the vorbis data to the Java layer
|
||||
int writeVorbisDataToEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* writeVorbisDataMethodId, char* buffer, int bytes);
|
||||
int writeVorbisDataToEncoderDataFeed(JNIEnv *env, jobject* encoderDataFeed, jmethodID* writeVorbisDataMethodId, char* buffer, int bytes, jbyteArray* jByteArrayWriteBuffer);
|
||||
|
||||
JNIEXPORT int JNICALL Java_org_xiph_vorbis_encoder_VorbisEncoder_startEncoding
|
||||
(JNIEnv *env, jclass cls, jlong sampleRate, jlong channels, jfloat quality, jobject encoderDataFeed);
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue