mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
FFmpeg extension cleanup
PiperOrigin-RevId: 303298804
This commit is contained in:
parent
af05ceac61
commit
9be4c08459
2 changed files with 33 additions and 31 deletions
|
|
@ -36,9 +36,10 @@ import java.util.List;
|
||||||
private static final int OUTPUT_BUFFER_SIZE_16BIT = 65536;
|
private static final int OUTPUT_BUFFER_SIZE_16BIT = 65536;
|
||||||
private static final int OUTPUT_BUFFER_SIZE_32BIT = OUTPUT_BUFFER_SIZE_16BIT * 2;
|
private static final int OUTPUT_BUFFER_SIZE_32BIT = OUTPUT_BUFFER_SIZE_16BIT * 2;
|
||||||
|
|
||||||
// Error codes matching ffmpeg_jni.cc.
|
// LINT.IfChange
|
||||||
private static final int DECODER_ERROR_INVALID_DATA = -1;
|
private static final int AUDIO_DECODER_ERROR_INVALID_DATA = -1;
|
||||||
private static final int DECODER_ERROR_OTHER = -2;
|
private static final int AUDIO_DECODER_ERROR_OTHER = -2;
|
||||||
|
// LINT.ThenChange(../../../../../../../jni/ffmpeg_jni.cc)
|
||||||
|
|
||||||
private final String codecName;
|
private final String codecName;
|
||||||
@Nullable private final byte[] extraData;
|
@Nullable private final byte[] extraData;
|
||||||
|
|
@ -107,13 +108,13 @@ import java.util.List;
|
||||||
int inputSize = inputData.limit();
|
int inputSize = inputData.limit();
|
||||||
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputBufferSize);
|
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputBufferSize);
|
||||||
int result = ffmpegDecode(nativeContext, inputData, inputSize, outputData, outputBufferSize);
|
int result = ffmpegDecode(nativeContext, inputData, inputSize, outputData, outputBufferSize);
|
||||||
if (result == DECODER_ERROR_INVALID_DATA) {
|
if (result == AUDIO_DECODER_ERROR_INVALID_DATA) {
|
||||||
// Treat invalid data errors as non-fatal to match the behavior of MediaCodec. No output will
|
// Treat invalid data errors as non-fatal to match the behavior of MediaCodec. No output will
|
||||||
// be produced for this buffer, so mark it as decode-only to ensure that the audio sink's
|
// be produced for this buffer, so mark it as decode-only to ensure that the audio sink's
|
||||||
// position is reset when more audio is produced.
|
// position is reset when more audio is produced.
|
||||||
outputBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY);
|
outputBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY);
|
||||||
return null;
|
return null;
|
||||||
} else if (result == DECODER_ERROR_OTHER) {
|
} else if (result == AUDIO_DECODER_ERROR_OTHER) {
|
||||||
return new FfmpegDecoderException("Error decoding (see logcat).");
|
return new FfmpegDecoderException("Error decoding (see logcat).");
|
||||||
}
|
}
|
||||||
if (!hasOutputFormat) {
|
if (!hasOutputFormat) {
|
||||||
|
|
@ -121,8 +122,8 @@ import java.util.List;
|
||||||
sampleRate = ffmpegGetSampleRate(nativeContext);
|
sampleRate = ffmpegGetSampleRate(nativeContext);
|
||||||
if (sampleRate == 0 && "alac".equals(codecName)) {
|
if (sampleRate == 0 && "alac".equals(codecName)) {
|
||||||
Assertions.checkNotNull(extraData);
|
Assertions.checkNotNull(extraData);
|
||||||
// ALAC decoder did not set the sample rate in earlier versions of FFMPEG.
|
// ALAC decoder did not set the sample rate in earlier versions of FFmpeg. See
|
||||||
// See https://trac.ffmpeg.org/ticket/6096
|
// https://trac.ffmpeg.org/ticket/6096.
|
||||||
ParsableByteArray parsableExtraData = new ParsableByteArray(extraData);
|
ParsableByteArray parsableExtraData = new ParsableByteArray(extraData);
|
||||||
parsableExtraData.setPosition(extraData.length - 4);
|
parsableExtraData.setPosition(extraData.length - 4);
|
||||||
sampleRate = parsableExtraData.readUnsignedIntToInt();
|
sampleRate = parsableExtraData.readUnsignedIntToInt();
|
||||||
|
|
@ -151,9 +152,7 @@ import java.util.List;
|
||||||
return sampleRate;
|
return sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Returns the encoding of output audio. */
|
||||||
* Returns the encoding of output audio.
|
|
||||||
*/
|
|
||||||
public @C.Encoding int getEncoding() {
|
public @C.Encoding int getEncoding() {
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
@ -215,13 +214,14 @@ import java.util.List;
|
||||||
int rawSampleRate,
|
int rawSampleRate,
|
||||||
int rawChannelCount);
|
int rawChannelCount);
|
||||||
|
|
||||||
private native int ffmpegDecode(long context, ByteBuffer inputData, int inputSize,
|
private native int ffmpegDecode(
|
||||||
ByteBuffer outputData, int outputSize);
|
long context, ByteBuffer inputData, int inputSize, ByteBuffer outputData, int outputSize);
|
||||||
|
|
||||||
private native int ffmpegGetChannelCount(long context);
|
private native int ffmpegGetChannelCount(long context);
|
||||||
|
|
||||||
private native int ffmpegGetSampleRate(long context);
|
private native int ffmpegGetSampleRate(long context);
|
||||||
|
|
||||||
private native long ffmpegReset(long context, @Nullable byte[] extraData);
|
private native long ffmpegReset(long context, @Nullable byte[] extraData);
|
||||||
|
|
||||||
private native void ffmpegRelease(long context);
|
private native void ffmpegRelease(long context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,6 @@ extern "C" {
|
||||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
||||||
__VA_ARGS__))
|
__VA_ARGS__))
|
||||||
|
|
||||||
#define AUDIO_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
|
||||||
extern "C" { \
|
|
||||||
JNIEXPORT RETURN_TYPE \
|
|
||||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
|
||||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
JNIEXPORT RETURN_TYPE \
|
|
||||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
|
||||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
#define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
|
#define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
|
||||||
extern "C" { \
|
extern "C" { \
|
||||||
JNIEXPORT RETURN_TYPE \
|
JNIEXPORT RETURN_TYPE \
|
||||||
|
|
@ -56,6 +46,16 @@ extern "C" {
|
||||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
|
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
|
||||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define AUDIO_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
||||||
|
extern "C" { \
|
||||||
|
JNIEXPORT RETURN_TYPE \
|
||||||
|
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
||||||
|
JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
JNIEXPORT RETURN_TYPE \
|
||||||
|
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
||||||
|
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define ERROR_STRING_BUFFER_LENGTH 256
|
#define ERROR_STRING_BUFFER_LENGTH 256
|
||||||
|
|
||||||
// Output format corresponding to AudioFormat.ENCODING_PCM_16BIT.
|
// Output format corresponding to AudioFormat.ENCODING_PCM_16BIT.
|
||||||
|
|
@ -63,9 +63,10 @@ static const AVSampleFormat OUTPUT_FORMAT_PCM_16BIT = AV_SAMPLE_FMT_S16;
|
||||||
// Output format corresponding to AudioFormat.ENCODING_PCM_FLOAT.
|
// Output format corresponding to AudioFormat.ENCODING_PCM_FLOAT.
|
||||||
static const AVSampleFormat OUTPUT_FORMAT_PCM_FLOAT = AV_SAMPLE_FMT_FLT;
|
static const AVSampleFormat OUTPUT_FORMAT_PCM_FLOAT = AV_SAMPLE_FMT_FLT;
|
||||||
|
|
||||||
// Error codes matching FfmpegAudioDecoder.java.
|
// LINT.IfChange
|
||||||
static const int DECODER_ERROR_INVALID_DATA = -1;
|
static const int AUDIO_DECODER_ERROR_INVALID_DATA = -1;
|
||||||
static const int DECODER_ERROR_OTHER = -2;
|
static const int AUDIO_DECODER_ERROR_OTHER = -2;
|
||||||
|
// LINT.ThenChange(../java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the AVCodec with the specified name, or NULL if it is not available.
|
* Returns the AVCodec with the specified name, or NULL if it is not available.
|
||||||
|
|
@ -83,7 +84,8 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes the packet into the output buffer, returning the number of bytes
|
* Decodes the packet into the output buffer, returning the number of bytes
|
||||||
* written, or a negative DECODER_ERROR constant value in the case of an error.
|
* written, or a negative AUDIO_DECODER_ERROR constant value in the case of an
|
||||||
|
* error.
|
||||||
*/
|
*/
|
||||||
int decodePacket(AVCodecContext *context, AVPacket *packet,
|
int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||||
uint8_t *outputBuffer, int outputSize);
|
uint8_t *outputBuffer, int outputSize);
|
||||||
|
|
@ -127,8 +129,8 @@ AUDIO_DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName,
|
||||||
rawChannelCount);
|
rawChannelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
|
AUDIO_DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
|
||||||
jint inputSize, jobject outputData, jint outputSize) {
|
jint inputSize, jobject outputData, jint outputSize) {
|
||||||
if (!context) {
|
if (!context) {
|
||||||
LOGE("Context must be non-NULL.");
|
LOGE("Context must be non-NULL.");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -260,8 +262,8 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||||
result = avcodec_send_packet(context, packet);
|
result = avcodec_send_packet(context, packet);
|
||||||
if (result) {
|
if (result) {
|
||||||
logError("avcodec_send_packet", result);
|
logError("avcodec_send_packet", result);
|
||||||
return result == AVERROR_INVALIDDATA ? DECODER_ERROR_INVALID_DATA
|
return result == AVERROR_INVALIDDATA ? AUDIO_DECODER_ERROR_INVALID_DATA
|
||||||
: DECODER_ERROR_OTHER;
|
: AUDIO_DECODER_ERROR_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dequeue output data until it runs out.
|
// Dequeue output data until it runs out.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue