1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <jni.h>
17 #include <stdlib.h>
18 #include <android/log.h>
19
20 extern "C" {
21 #ifdef __cplusplus
22 #define __STDC_CONSTANT_MACROS
23 #ifdef _STDINT_H
24 #undef _STDINT_H
25 #endif
26 #include <stdint.h>
27 #endif
28 #include <libavcodec/avcodec.h>
29 #include <libavutil/channel_layout.h>
30 #include <libavutil/error.h>
31 #include <libavutil/opt.h>
32 #include <libswresample/swresample.h>
33 }
34
35 #define LOG_TAG "ffmpeg_jni"
36 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
37 __VA_ARGS__))
38
39 #define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
40 extern "C" { \
41 JNIEXPORT RETURN_TYPE \
42 Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
43 JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
44 } \
45 JNIEXPORT RETURN_TYPE \
46 Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
47 JNIEnv *env, jobject thiz, ##__VA_ARGS__)
48
49 #define AUDIO_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
50 extern "C" { \
51 JNIEXPORT RETURN_TYPE \
52 Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
53 JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
54 } \
55 JNIEXPORT RETURN_TYPE \
56 Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
57 JNIEnv *env, jobject thiz, ##__VA_ARGS__)
58
59 #define ERROR_STRING_BUFFER_LENGTH 256
60
61 // Output format corresponding to AudioFormat.ENCODING_PCM_16BIT.
62 static const AVSampleFormat OUTPUT_FORMAT_PCM_16BIT = AV_SAMPLE_FMT_S16;
63 // Output format corresponding to AudioFormat.ENCODING_PCM_FLOAT.
64 static const AVSampleFormat OUTPUT_FORMAT_PCM_FLOAT = AV_SAMPLE_FMT_FLT;
65
66 // LINT.IfChange
67 static const int AUDIO_DECODER_ERROR_INVALID_DATA = -1;
68 static const int AUDIO_DECODER_ERROR_OTHER = -2;
69 // LINT.ThenChange(../java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java)
70
71 /**
72 * Returns the AVCodec with the specified name, or NULL if it is not available.
73 */
74 AVCodec *getCodecByName(JNIEnv* env, jstring codecName);
75
76 /**
77 * Allocates and opens a new AVCodecContext for the specified codec, passing the
78 * provided extraData as initialization data for the decoder if it is non-NULL.
79 * Returns the created context.
80 */
81 AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
82 jboolean outputFloat, jint rawSampleRate,
83 jint rawChannelCount);
84
85 /**
86 * Decodes the packet into the output buffer, returning the number of bytes
87 * written, or a negative AUDIO_DECODER_ERROR constant value in the case of an
88 * error.
89 */
90 int decodePacket(AVCodecContext *context, AVPacket *packet,
91 uint8_t *outputBuffer, int outputSize);
92
93 /**
94 * Outputs a log message describing the avcodec error number.
95 */
96 void logError(const char *functionName, int errorNumber);
97
98 /**
99 * Releases the specified context.
100 */
101 void releaseContext(AVCodecContext *context);
102
JNI_OnLoad(JavaVM * vm,void * reserved)103 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
104 JNIEnv *env;
105 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
106 return -1;
107 }
108 avcodec_register_all();
109 return JNI_VERSION_1_6;
110 }
111
LIBRARY_FUNC(jstring,ffmpegGetVersion)112 LIBRARY_FUNC(jstring, ffmpegGetVersion) {
113 return env->NewStringUTF(LIBAVCODEC_IDENT);
114 }
115
LIBRARY_FUNC(jboolean,ffmpegHasDecoder,jstring codecName)116 LIBRARY_FUNC(jboolean, ffmpegHasDecoder, jstring codecName) {
117 return getCodecByName(env, codecName) != NULL;
118 }
119
AUDIO_DECODER_FUNC(jlong,ffmpegInitialize,jstring codecName,jbyteArray extraData,jboolean outputFloat,jint rawSampleRate,jint rawChannelCount)120 AUDIO_DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName,
121 jbyteArray extraData, jboolean outputFloat,
122 jint rawSampleRate, jint rawChannelCount) {
123 AVCodec *codec = getCodecByName(env, codecName);
124 if (!codec) {
125 LOGE("Codec not found.");
126 return 0L;
127 }
128 return (jlong)createContext(env, codec, extraData, outputFloat, rawSampleRate,
129 rawChannelCount);
130 }
131
AUDIO_DECODER_FUNC(jint,ffmpegDecode,jlong context,jobject inputData,jint inputSize,jobject outputData,jint outputSize)132 AUDIO_DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
133 jint inputSize, jobject outputData, jint outputSize) {
134 if (!context) {
135 LOGE("Context must be non-NULL.");
136 return -1;
137 }
138 if (!inputData || !outputData) {
139 LOGE("Input and output buffers must be non-NULL.");
140 return -1;
141 }
142 if (inputSize < 0) {
143 LOGE("Invalid input buffer size: %d.", inputSize);
144 return -1;
145 }
146 if (outputSize < 0) {
147 LOGE("Invalid output buffer length: %d", outputSize);
148 return -1;
149 }
150 uint8_t *inputBuffer = (uint8_t *) env->GetDirectBufferAddress(inputData);
151 uint8_t *outputBuffer = (uint8_t *) env->GetDirectBufferAddress(outputData);
152 AVPacket packet;
153 av_init_packet(&packet);
154 packet.data = inputBuffer;
155 packet.size = inputSize;
156 return decodePacket((AVCodecContext *) context, &packet, outputBuffer,
157 outputSize);
158 }
159
AUDIO_DECODER_FUNC(jint,ffmpegGetChannelCount,jlong context)160 AUDIO_DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
161 if (!context) {
162 LOGE("Context must be non-NULL.");
163 return -1;
164 }
165 return ((AVCodecContext *) context)->channels;
166 }
167
AUDIO_DECODER_FUNC(jint,ffmpegGetSampleRate,jlong context)168 AUDIO_DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
169 if (!context) {
170 LOGE("Context must be non-NULL.");
171 return -1;
172 }
173 return ((AVCodecContext *) context)->sample_rate;
174 }
175
AUDIO_DECODER_FUNC(jlong,ffmpegReset,jlong jContext,jbyteArray extraData)176 AUDIO_DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
177 AVCodecContext *context = (AVCodecContext *) jContext;
178 if (!context) {
179 LOGE("Tried to reset without a context.");
180 return 0L;
181 }
182
183 AVCodecID codecId = context->codec_id;
184 if (codecId == AV_CODEC_ID_TRUEHD) {
185 // Release and recreate the context if the codec is TrueHD.
186 // TODO: Figure out why flushing doesn't work for this codec.
187 releaseContext(context);
188 AVCodec *codec = avcodec_find_decoder(codecId);
189 if (!codec) {
190 LOGE("Unexpected error finding codec %d.", codecId);
191 return 0L;
192 }
193 jboolean outputFloat =
194 (jboolean)(context->request_sample_fmt == OUTPUT_FORMAT_PCM_FLOAT);
195 return (jlong)createContext(env, codec, extraData, outputFloat,
196 /* rawSampleRate= */ -1,
197 /* rawChannelCount= */ -1);
198 }
199
200 avcodec_flush_buffers(context);
201 return (jlong) context;
202 }
203
AUDIO_DECODER_FUNC(void,ffmpegRelease,jlong context)204 AUDIO_DECODER_FUNC(void, ffmpegRelease, jlong context) {
205 if (context) {
206 releaseContext((AVCodecContext *) context);
207 }
208 }
209
getCodecByName(JNIEnv * env,jstring codecName)210 AVCodec *getCodecByName(JNIEnv* env, jstring codecName) {
211 if (!codecName) {
212 return NULL;
213 }
214 const char *codecNameChars = env->GetStringUTFChars(codecName, NULL);
215 AVCodec *codec = avcodec_find_decoder_by_name(codecNameChars);
216 env->ReleaseStringUTFChars(codecName, codecNameChars);
217 return codec;
218 }
219
createContext(JNIEnv * env,AVCodec * codec,jbyteArray extraData,jboolean outputFloat,jint rawSampleRate,jint rawChannelCount)220 AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
221 jboolean outputFloat, jint rawSampleRate,
222 jint rawChannelCount) {
223 AVCodecContext *context = avcodec_alloc_context3(codec);
224 if (!context) {
225 LOGE("Failed to allocate context.");
226 return NULL;
227 }
228 context->request_sample_fmt =
229 outputFloat ? OUTPUT_FORMAT_PCM_FLOAT : OUTPUT_FORMAT_PCM_16BIT;
230 if (extraData) {
231 jsize size = env->GetArrayLength(extraData);
232 context->extradata_size = size;
233 context->extradata =
234 (uint8_t *) av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
235 if (!context->extradata) {
236 LOGE("Failed to allocate extradata.");
237 releaseContext(context);
238 return NULL;
239 }
240 env->GetByteArrayRegion(extraData, 0, size, (jbyte *) context->extradata);
241 }
242 if (context->codec_id == AV_CODEC_ID_PCM_MULAW ||
243 context->codec_id == AV_CODEC_ID_PCM_ALAW) {
244 context->sample_rate = rawSampleRate;
245 context->channels = rawChannelCount;
246 context->channel_layout = av_get_default_channel_layout(rawChannelCount);
247 }
248 context->err_recognition = AV_EF_IGNORE_ERR;
249 int result = avcodec_open2(context, codec, NULL);
250 if (result < 0) {
251 logError("avcodec_open2", result);
252 releaseContext(context);
253 return NULL;
254 }
255 return context;
256 }
257
decodePacket(AVCodecContext * context,AVPacket * packet,uint8_t * outputBuffer,int outputSize)258 int decodePacket(AVCodecContext *context, AVPacket *packet,
259 uint8_t *outputBuffer, int outputSize) {
260 int result = 0;
261 // Queue input data.
262 result = avcodec_send_packet(context, packet);
263 if (result) {
264 logError("avcodec_send_packet", result);
265 return result == AVERROR_INVALIDDATA ? AUDIO_DECODER_ERROR_INVALID_DATA
266 : AUDIO_DECODER_ERROR_OTHER;
267 }
268
269 // Dequeue output data until it runs out.
270 int outSize = 0;
271 while (true) {
272 AVFrame *frame = av_frame_alloc();
273 if (!frame) {
274 LOGE("Failed to allocate output frame.");
275 return -1;
276 }
277 result = avcodec_receive_frame(context, frame);
278 if (result) {
279 av_frame_free(&frame);
280 if (result == AVERROR(EAGAIN)) {
281 break;
282 }
283 logError("avcodec_receive_frame", result);
284 return result;
285 }
286
287 // Resample output.
288 AVSampleFormat sampleFormat = context->sample_fmt;
289 int channelCount = context->channels;
290 int channelLayout = context->channel_layout;
291 int sampleRate = context->sample_rate;
292 int sampleCount = frame->nb_samples;
293 int dataSize = av_samples_get_buffer_size(NULL, channelCount, sampleCount,
294 sampleFormat, 1);
295 SwrContext *resampleContext;
296 if (context->opaque) {
297 resampleContext = (SwrContext *)context->opaque;
298 } else {
299 resampleContext = swr_alloc();
300 av_opt_set_int(resampleContext, "in_channel_layout", channelLayout, 0);
301 av_opt_set_int(resampleContext, "out_channel_layout", channelLayout, 0);
302 av_opt_set_int(resampleContext, "in_sample_rate", sampleRate, 0);
303 av_opt_set_int(resampleContext, "out_sample_rate", sampleRate, 0);
304 av_opt_set_int(resampleContext, "in_sample_fmt", sampleFormat, 0);
305 // The output format is always the requested format.
306 av_opt_set_int(resampleContext, "out_sample_fmt",
307 context->request_sample_fmt, 0);
308 result = swr_init(resampleContext);
309 if (result < 0) {
310 logError("swr_init", result);
311 av_frame_free(&frame);
312 return -1;
313 }
314 context->opaque = resampleContext;
315 }
316 int inSampleSize = av_get_bytes_per_sample(sampleFormat);
317 int outSampleSize = av_get_bytes_per_sample(context->request_sample_fmt);
318 int outSamples = swr_get_out_samples(resampleContext, sampleCount);
319 int bufferOutSize = outSampleSize * channelCount * outSamples;
320 if (outSize + bufferOutSize > outputSize) {
321 LOGE("Output buffer size (%d) too small for output data (%d).",
322 outputSize, outSize + bufferOutSize);
323 av_frame_free(&frame);
324 return -1;
325 }
326 result = swr_convert(resampleContext, &outputBuffer, bufferOutSize,
327 (const uint8_t **)frame->data, frame->nb_samples);
328 av_frame_free(&frame);
329 if (result < 0) {
330 logError("swr_convert", result);
331 return result;
332 }
333 int available = swr_get_out_samples(resampleContext, 0);
334 if (available != 0) {
335 LOGE("Expected no samples remaining after resampling, but found %d.",
336 available);
337 return -1;
338 }
339 outputBuffer += bufferOutSize;
340 outSize += bufferOutSize;
341 }
342 return outSize;
343 }
344
logError(const char * functionName,int errorNumber)345 void logError(const char *functionName, int errorNumber) {
346 char *buffer = (char *) malloc(ERROR_STRING_BUFFER_LENGTH * sizeof(char));
347 av_strerror(errorNumber, buffer, ERROR_STRING_BUFFER_LENGTH);
348 LOGE("Error in %s: %s", functionName, buffer);
349 free(buffer);
350 }
351
releaseContext(AVCodecContext * context)352 void releaseContext(AVCodecContext *context) {
353 if (!context) {
354 return;
355 }
356 SwrContext *swrContext;
357 if ((swrContext = (SwrContext *)context->opaque)) {
358 swr_free(&swrContext);
359 context->opaque = NULL;
360 }
361 avcodec_free_context(&context);
362 }
363
364