Commit f2229d92 by olly Committed by Oliver Woodman

Move FlacJni to FlacDecoderJni

If/when we add the ability to query version information,
such methods will go into FlacLibrary for consistency with
the other extensions. The difference for Flac is that
since the decoder JNI is used by the extractor too, it
needs splitting into a separate from from FlacDecoder.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=132904665
parent de67fa50
...@@ -30,7 +30,7 @@ import java.util.List; ...@@ -30,7 +30,7 @@ import java.util.List;
SimpleDecoder<DecoderInputBuffer, SimpleOutputBuffer, FlacDecoderException> { SimpleDecoder<DecoderInputBuffer, SimpleOutputBuffer, FlacDecoderException> {
private final int maxOutputBufferSize; private final int maxOutputBufferSize;
private final FlacJni decoder; private final FlacDecoderJni decoderJni;
/** /**
* Creates a Flac decoder. * Creates a Flac decoder.
...@@ -47,11 +47,11 @@ import java.util.List; ...@@ -47,11 +47,11 @@ import java.util.List;
if (initializationData.size() != 1) { if (initializationData.size() != 1) {
throw new FlacDecoderException("Initialization data must be of length 1"); throw new FlacDecoderException("Initialization data must be of length 1");
} }
decoder = new FlacJni(); decoderJni = new FlacDecoderJni();
decoder.setData(ByteBuffer.wrap(initializationData.get(0))); decoderJni.setData(ByteBuffer.wrap(initializationData.get(0)));
FlacStreamInfo streamInfo; FlacStreamInfo streamInfo;
try { try {
streamInfo = decoder.decodeMetadata(); streamInfo = decoderJni.decodeMetadata();
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
// Never happens. // Never happens.
throw new IllegalStateException(e); throw new IllegalStateException(e);
...@@ -83,13 +83,13 @@ import java.util.List; ...@@ -83,13 +83,13 @@ import java.util.List;
public FlacDecoderException decode(DecoderInputBuffer inputBuffer, public FlacDecoderException decode(DecoderInputBuffer inputBuffer,
SimpleOutputBuffer outputBuffer, boolean reset) { SimpleOutputBuffer outputBuffer, boolean reset) {
if (reset) { if (reset) {
decoder.flush(); decoderJni.flush();
} }
decoder.setData(inputBuffer.data); decoderJni.setData(inputBuffer.data);
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, maxOutputBufferSize); ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, maxOutputBufferSize);
int result; int result;
try { try {
result = decoder.decodeSample(outputData); result = decoderJni.decodeSample(outputData);
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
// Never happens. // Never happens.
throw new IllegalStateException(e); throw new IllegalStateException(e);
...@@ -105,7 +105,7 @@ import java.util.List; ...@@ -105,7 +105,7 @@ import java.util.List;
@Override @Override
public void release() { public void release() {
super.release(); super.release();
decoder.release(); decoderJni.release();
} }
} }
......
...@@ -24,7 +24,7 @@ import java.nio.ByteBuffer; ...@@ -24,7 +24,7 @@ import java.nio.ByteBuffer;
/** /**
* JNI wrapper for the libflac Flac decoder. * JNI wrapper for the libflac Flac decoder.
*/ */
/* package */ final class FlacJni { /* package */ final class FlacDecoderJni {
private static final int TEMP_BUFFER_SIZE = 8192; // The same buffer size which libflac has private static final int TEMP_BUFFER_SIZE = 8192; // The same buffer size which libflac has
...@@ -35,7 +35,7 @@ import java.nio.ByteBuffer; ...@@ -35,7 +35,7 @@ import java.nio.ByteBuffer;
private boolean endOfExtractorInput; private boolean endOfExtractorInput;
private byte[] tempBuffer; private byte[] tempBuffer;
public FlacJni() throws FlacDecoderException { public FlacDecoderJni() throws FlacDecoderException {
if (!FlacLibrary.isAvailable()) { if (!FlacLibrary.isAvailable()) {
throw new FlacDecoderException("Failed to load decoder native libraries."); throw new FlacDecoderException("Failed to load decoder native libraries.");
} }
......
...@@ -57,7 +57,7 @@ public final class FlacExtractor implements Extractor { ...@@ -57,7 +57,7 @@ public final class FlacExtractor implements Extractor {
private ExtractorOutput extractorOutput; private ExtractorOutput extractorOutput;
private TrackOutput trackOutput; private TrackOutput trackOutput;
private FlacJni decoder; private FlacDecoderJni decoderJni;
private boolean metadataParsed; private boolean metadataParsed;
...@@ -70,7 +70,7 @@ public final class FlacExtractor implements Extractor { ...@@ -70,7 +70,7 @@ public final class FlacExtractor implements Extractor {
trackOutput = extractorOutput.track(0); trackOutput = extractorOutput.track(0);
extractorOutput.endTracks(); extractorOutput.endTracks();
try { try {
decoder = new FlacJni(); decoderJni = new FlacDecoderJni();
} catch (FlacDecoderException e) { } catch (FlacDecoderException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
...@@ -86,24 +86,24 @@ public final class FlacExtractor implements Extractor { ...@@ -86,24 +86,24 @@ public final class FlacExtractor implements Extractor {
@Override @Override
public int read(final ExtractorInput input, PositionHolder seekPosition) public int read(final ExtractorInput input, PositionHolder seekPosition)
throws IOException, InterruptedException { throws IOException, InterruptedException {
decoder.setData(input); decoderJni.setData(input);
if (!metadataParsed) { if (!metadataParsed) {
final FlacStreamInfo streamInfo; final FlacStreamInfo streamInfo;
try { try {
streamInfo = decoder.decodeMetadata(); streamInfo = decoderJni.decodeMetadata();
if (streamInfo == null) { if (streamInfo == null) {
throw new IOException("Metadata decoding failed"); throw new IOException("Metadata decoding failed");
} }
} catch (IOException e){ } catch (IOException e){
decoder.reset(0); decoderJni.reset(0);
input.setRetryPosition(0, e); input.setRetryPosition(0, e);
throw e; // never executes throw e; // never executes
} }
metadataParsed = true; metadataParsed = true;
extractorOutput.seekMap(new SeekMap() { extractorOutput.seekMap(new SeekMap() {
final boolean isSeekable = decoder.getSeekPosition(0) != -1; final boolean isSeekable = decoderJni.getSeekPosition(0) != -1;
final long durationUs = streamInfo.durationUs(); final long durationUs = streamInfo.durationUs();
@Override @Override
...@@ -113,7 +113,7 @@ public final class FlacExtractor implements Extractor { ...@@ -113,7 +113,7 @@ public final class FlacExtractor implements Extractor {
@Override @Override
public long getPosition(long timeUs) { public long getPosition(long timeUs) {
return isSeekable ? decoder.getSeekPosition(timeUs) : 0; return isSeekable ? decoderJni.getSeekPosition(timeUs) : 0;
} }
@Override @Override
...@@ -133,13 +133,13 @@ public final class FlacExtractor implements Extractor { ...@@ -133,13 +133,13 @@ public final class FlacExtractor implements Extractor {
} }
outputBuffer.reset(); outputBuffer.reset();
long lastDecodePosition = decoder.getDecodePosition(); long lastDecodePosition = decoderJni.getDecodePosition();
int size; int size;
try { try {
size = decoder.decodeSample(outputByteBuffer); size = decoderJni.decodeSample(outputByteBuffer);
} catch (IOException e){ } catch (IOException e){
if (lastDecodePosition >= 0) { if (lastDecodePosition >= 0) {
decoder.reset(lastDecodePosition); decoderJni.reset(lastDecodePosition);
input.setRetryPosition(lastDecodePosition, e); input.setRetryPosition(lastDecodePosition, e);
} }
throw e; throw e;
...@@ -148,11 +148,10 @@ public final class FlacExtractor implements Extractor { ...@@ -148,11 +148,10 @@ public final class FlacExtractor implements Extractor {
return RESULT_END_OF_INPUT; return RESULT_END_OF_INPUT;
} }
trackOutput.sampleData(outputBuffer, size); trackOutput.sampleData(outputBuffer, size);
trackOutput.sampleMetadata(decoderJni.getLastSampleTimestamp(), C.BUFFER_FLAG_KEY_FRAME, size,
0, null);
trackOutput.sampleMetadata(decoder.getLastSampleTimestamp(), C.BUFFER_FLAG_KEY_FRAME, size, 0, return decoderJni.isEndOfData() ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
null);
return decoder.isEndOfData() ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
} }
@Override @Override
...@@ -160,13 +159,13 @@ public final class FlacExtractor implements Extractor { ...@@ -160,13 +159,13 @@ public final class FlacExtractor implements Extractor {
if (position == 0) { if (position == 0) {
metadataParsed = false; metadataParsed = false;
} }
decoder.reset(position); decoderJni.reset(position);
} }
@Override @Override
public void release() { public void release() {
decoder.release(); decoderJni.release();
decoder = null; decoderJni = null;
} }
} }
...@@ -15,11 +15,8 @@ ...@@ -15,11 +15,8 @@
*/ */
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
#include <cstdlib> #include <cstdlib>
#include "include/flac_parser.h" #include "include/flac_parser.h"
#define LOG_TAG "flac_jni" #define LOG_TAG "flac_jni"
...@@ -28,23 +25,23 @@ ...@@ -28,23 +25,23 @@
#define ALOGV(...) \ #define ALOGV(...) \
((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#define FUNC(RETURN_TYPE, NAME, ...) \ #define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
extern "C" { \ extern "C" { \
JNIEXPORT RETURN_TYPE \ JNIEXPORT RETURN_TYPE \
Java_com_google_android_exoplayer2_ext_flac_FlacJni_##NAME( \ Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
JNIEnv *env, jobject thiz, ##__VA_ARGS__); \ JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
} \ } \
JNIEXPORT RETURN_TYPE \ JNIEXPORT RETURN_TYPE \
Java_com_google_android_exoplayer2_ext_flac_FlacJni_##NAME( \ Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
JNIEnv *env, jobject thiz, ##__VA_ARGS__) JNIEnv *env, jobject thiz, ##__VA_ARGS__)
class JavaDataSource : public DataSource { class JavaDataSource : public DataSource {
public: public:
void setFlacJni(JNIEnv *env, jobject flacJni) { void setFlacDecoderJni(JNIEnv *env, jobject flacDecoderJni) {
this->env = env; this->env = env;
this->flacJni = flacJni; this->flacDecoderJni = flacDecoderJni;
if (mid == NULL) { if (mid == NULL) {
jclass cls = env->GetObjectClass(flacJni); jclass cls = env->GetObjectClass(flacDecoderJni);
mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I"); mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
env->DeleteLocalRef(cls); env->DeleteLocalRef(cls);
} }
...@@ -52,7 +49,7 @@ class JavaDataSource : public DataSource { ...@@ -52,7 +49,7 @@ class JavaDataSource : public DataSource {
ssize_t readAt(off64_t offset, void *const data, size_t size) { ssize_t readAt(off64_t offset, void *const data, size_t size) {
jobject byteBuffer = env->NewDirectByteBuffer(data, size); jobject byteBuffer = env->NewDirectByteBuffer(data, size);
int result = env->CallIntMethod(flacJni, mid, byteBuffer); int result = env->CallIntMethod(flacDecoderJni, mid, byteBuffer);
if (env->ExceptionOccurred()) { if (env->ExceptionOccurred()) {
result = -1; result = -1;
} }
...@@ -62,7 +59,7 @@ class JavaDataSource : public DataSource { ...@@ -62,7 +59,7 @@ class JavaDataSource : public DataSource {
private: private:
JNIEnv *env; JNIEnv *env;
jobject flacJni; jobject flacDecoderJni;
jmethodID mid; jmethodID mid;
}; };
...@@ -81,7 +78,7 @@ struct Context { ...@@ -81,7 +78,7 @@ struct Context {
} }
}; };
FUNC(jlong, flacInit) { DECODER_FUNC(jlong, flacInit) {
Context *context = new Context; Context *context = new Context;
if (!context->parser->init()) { if (!context->parser->init()) {
delete context; delete context;
...@@ -90,9 +87,9 @@ FUNC(jlong, flacInit) { ...@@ -90,9 +87,9 @@ FUNC(jlong, flacInit) {
return reinterpret_cast<intptr_t>(context); return reinterpret_cast<intptr_t>(context);
} }
FUNC(jobject, flacDecodeMetadata, jlong jContext) { DECODER_FUNC(jobject, flacDecodeMetadata, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacJni(env, thiz); context->source->setFlacDecoderJni(env, thiz);
if (!context->parser->decodeMetadata()) { if (!context->parser->decodeMetadata()) {
return NULL; return NULL;
} }
...@@ -112,17 +109,17 @@ FUNC(jobject, flacDecodeMetadata, jlong jContext) { ...@@ -112,17 +109,17 @@ FUNC(jobject, flacDecodeMetadata, jlong jContext) {
streamInfo.total_samples); streamInfo.total_samples);
} }
FUNC(jint, flacDecodeToBuffer, jlong jContext, jobject jOutputBuffer) { DECODER_FUNC(jint, flacDecodeToBuffer, jlong jContext, jobject jOutputBuffer) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacJni(env, thiz); context->source->setFlacDecoderJni(env, thiz);
void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer); void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer);
jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer); jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer);
return context->parser->readBuffer(outputBuffer, outputSize); return context->parser->readBuffer(outputBuffer, outputSize);
} }
FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) { DECODER_FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacJni(env, thiz); context->source->setFlacDecoderJni(env, thiz);
jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL); jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL);
jint outputSize = env->GetArrayLength(jOutputArray); jint outputSize = env->GetArrayLength(jOutputArray);
int count = context->parser->readBuffer(outputBuffer, outputSize); int count = context->parser->readBuffer(outputBuffer, outputSize);
...@@ -130,38 +127,38 @@ FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) { ...@@ -130,38 +127,38 @@ FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) {
return count; return count;
} }
FUNC(jlong, flacGetDecodePosition, jlong jContext) { DECODER_FUNC(jlong, flacGetDecodePosition, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getDecodePosition(); return context->parser->getDecodePosition();
} }
FUNC(jlong, flacGetLastTimestamp, jlong jContext) { DECODER_FUNC(jlong, flacGetLastTimestamp, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getLastTimestamp(); return context->parser->getLastTimestamp();
} }
FUNC(jlong, flacGetSeekPosition, jlong jContext, jlong timeUs) { DECODER_FUNC(jlong, flacGetSeekPosition, jlong jContext, jlong timeUs) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getSeekPosition(timeUs); return context->parser->getSeekPosition(timeUs);
} }
FUNC(jstring, flacGetStateString, jlong jContext) { DECODER_FUNC(jstring, flacGetStateString, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
const char *str = context->parser->getDecoderStateString(); const char *str = context->parser->getDecoderStateString();
return env->NewStringUTF(str); return env->NewStringUTF(str);
} }
FUNC(void, flacFlush, jlong jContext) { DECODER_FUNC(void, flacFlush, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
context->parser->flush(); context->parser->flush();
} }
FUNC(void, flacReset, jlong jContext, jlong newPosition) { DECODER_FUNC(void, flacReset, jlong jContext, jlong newPosition) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
context->parser->reset(newPosition); context->parser->reset(newPosition);
} }
FUNC(void, flacRelease, jlong jContext) { DECODER_FUNC(void, flacRelease, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext); Context *context = reinterpret_cast<Context *>(jContext);
delete context; delete context;
} }
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
} }
# Some members of this class are being accessed from native methods. Keep them unobfuscated. # Some members of this class are being accessed from native methods. Keep them unobfuscated.
-keep class com.google.android.exoplayer2.ext.flac.FlacJni { -keep class com.google.android.exoplayer2.ext.flac.FlacDecoderJni {
*; *;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment