Skip to content

Commit 648b167

Browse files
committed
Migrate to FFmpeg 6.0
These changes are also compatible with FFmpeg 5.1, which is now minimum supported version. Also set -Wl,-Bsymbolic flag via target_link_options command which is more correct.
1 parent 0a016b5 commit 648b167

File tree

4 files changed

+33
-31
lines changed

4 files changed

+33
-31
lines changed

libraries/decoder_ffmpeg/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ HOST_PLATFORM="linux-x86_64"
4242
```
4343

4444
* Fetch FFmpeg and checkout an appropriate branch. We cannot guarantee
45-
compatibility with all versions of FFmpeg. We currently recommend version 4.2:
45+
compatibility with all versions of FFmpeg. We currently recommend version 6.0:
4646

4747
```
4848
cd "<preferred location for ffmpeg>" && \
4949
git clone git://source.ffmpeg.org/ffmpeg && \
5050
cd ffmpeg && \
51-
git checkout release/4.2 && \
51+
git checkout release/6.0 && \
5252
FFMPEG_PATH="$(pwd)"
5353
```
5454

libraries/decoder_ffmpeg/src/main/jni/CMakeLists.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ set(CMAKE_CXX_STANDARD 11)
2121

2222
project(libffmpegJNI C CXX)
2323

24-
# Additional flags needed for "arm64-v8a" from NDK 23.1.7779620 and above.
25-
# See https://github.com/google/ExoPlayer/issues/9933#issuecomment-1029775358.
26-
if(${ANDROID_ABI} MATCHES "arm64-v8a")
27-
set(CMAKE_CXX_FLAGS "-Wl,-Bsymbolic")
28-
endif()
29-
3024
set(ffmpeg_location "${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg")
3125
set(ffmpeg_binaries "${ffmpeg_location}/android-libs/${ANDROID_ABI}")
3226

@@ -56,3 +50,9 @@ target_link_libraries(ffmpegJNI
5650
PRIVATE avcodec
5751
PRIVATE avutil
5852
PRIVATE ${android_log_lib})
53+
54+
# Additional flags needed for "arm64-v8a" from NDK 23.1.7779620 and above.
55+
# See https://github.com/google/ExoPlayer/issues/9933#issuecomment-1029775358.
56+
if(ANDROID_ABI STREQUAL "arm64-v8a")
57+
target_link_options(ffmpegJNI PRIVATE "-Wl,-Bsymbolic")
58+
endif()

libraries/decoder_ffmpeg/src/main/jni/build_ffmpeg.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ COMMON_OPTIONS="
3535
--disable-postproc
3636
--disable-avfilter
3737
--disable-symver
38-
--disable-avresample
3938
--enable-swresample
4039
--extra-ldexeflags=-pie
40+
--disable-v4l2-m2m
41+
--disable-vulkan
4142
"
4243
TOOLCHAIN_PREFIX="${NDK_PATH}/toolchains/llvm/prebuilt/${HOST_PLATFORM}/bin"
4344
for decoder in "${ENABLED_DECODERS[@]}"

libraries/decoder_ffmpeg/src/main/jni/ffmpeg_jni.cc

+23-22
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ static jmethodID growOutputBufferMethod;
7474
/**
7575
* Returns the AVCodec with the specified name, or NULL if it is not available.
7676
*/
77-
AVCodec *getCodecByName(JNIEnv *env, jstring codecName);
77+
const AVCodec *getCodecByName(JNIEnv *env, jstring codecName);
7878

7979
/**
8080
* Allocates and opens a new AVCodecContext for the specified codec, passing the
8181
* provided extraData as initialization data for the decoder if it is non-NULL.
8282
* Returns the created context.
8383
*/
84-
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
84+
AVCodecContext *createContext(JNIEnv *env, const AVCodec *codec, jbyteArray extraData,
8585
jboolean outputFloat, jint rawSampleRate,
8686
jint rawChannelCount);
8787

@@ -137,7 +137,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
137137
LOGE("JNI_OnLoad: GetMethodID failed");
138138
return -1;
139139
}
140-
avcodec_register_all();
141140
return JNI_VERSION_1_6;
142141
}
143142

@@ -156,7 +155,7 @@ LIBRARY_FUNC(jboolean, ffmpegHasDecoder, jstring codecName) {
156155
AUDIO_DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName,
157156
jbyteArray extraData, jboolean outputFloat,
158157
jint rawSampleRate, jint rawChannelCount) {
159-
AVCodec *codec = getCodecByName(env, codecName);
158+
const AVCodec *codec = getCodecByName(env, codecName);
160159
if (!codec) {
161160
LOGE("Codec not found.");
162161
return 0L;
@@ -186,13 +185,17 @@ AUDIO_DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
186185
}
187186
uint8_t *inputBuffer = (uint8_t *)env->GetDirectBufferAddress(inputData);
188187
uint8_t *outputBuffer = (uint8_t *)env->GetDirectBufferAddress(outputData);
189-
AVPacket packet;
190-
av_init_packet(&packet);
191-
packet.data = inputBuffer;
192-
packet.size = inputSize;
193-
return decodePacket((AVCodecContext *)context, &packet, outputBuffer,
194-
outputSize,
195-
GrowOutputBufferCallback{env, thiz, decoderOutputBuffer});
188+
AVPacket* packet = av_packet_alloc();
189+
if (!packet) {
190+
LOGE("Failed to allocate packet.");
191+
return -1;
192+
}
193+
packet->data = inputBuffer;
194+
packet->size = inputSize;
195+
const int ret = decodePacket((AVCodecContext *)context, packet, outputBuffer,
196+
outputSize, GrowOutputBufferCallback{env, thiz, decoderOutputBuffer});
197+
av_packet_free(&packet);
198+
return ret;
196199
}
197200

198201
uint8_t *GrowOutputBufferCallback::operator()(int requiredSize) const {
@@ -211,7 +214,7 @@ AUDIO_DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
211214
LOGE("Context must be non-NULL.");
212215
return -1;
213216
}
214-
return ((AVCodecContext *)context)->channels;
217+
return ((AVCodecContext *)context)->ch_layout.nb_channels;
215218
}
216219

217220
AUDIO_DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
@@ -234,7 +237,7 @@ AUDIO_DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
234237
// Release and recreate the context if the codec is TrueHD.
235238
// TODO: Figure out why flushing doesn't work for this codec.
236239
releaseContext(context);
237-
AVCodec *codec = avcodec_find_decoder(codecId);
240+
const AVCodec *codec = avcodec_find_decoder(codecId);
238241
if (!codec) {
239242
LOGE("Unexpected error finding codec %d.", codecId);
240243
return 0L;
@@ -256,17 +259,17 @@ AUDIO_DECODER_FUNC(void, ffmpegRelease, jlong context) {
256259
}
257260
}
258261

259-
AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
262+
const AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
260263
if (!codecName) {
261264
return NULL;
262265
}
263266
const char *codecNameChars = env->GetStringUTFChars(codecName, NULL);
264-
AVCodec *codec = avcodec_find_decoder_by_name(codecNameChars);
267+
const AVCodec *codec = avcodec_find_decoder_by_name(codecNameChars);
265268
env->ReleaseStringUTFChars(codecName, codecNameChars);
266269
return codec;
267270
}
268271

269-
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
272+
AVCodecContext *createContext(JNIEnv *env, const AVCodec *codec, jbyteArray extraData,
270273
jboolean outputFloat, jint rawSampleRate,
271274
jint rawChannelCount) {
272275
AVCodecContext *context = avcodec_alloc_context3(codec);
@@ -291,8 +294,7 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
291294
if (context->codec_id == AV_CODEC_ID_PCM_MULAW ||
292295
context->codec_id == AV_CODEC_ID_PCM_ALAW) {
293296
context->sample_rate = rawSampleRate;
294-
context->channels = rawChannelCount;
295-
context->channel_layout = av_get_default_channel_layout(rawChannelCount);
297+
av_channel_layout_default(&context->ch_layout, rawChannelCount);
296298
}
297299
context->err_recognition = AV_EF_IGNORE_ERR;
298300
int result = avcodec_open2(context, codec, NULL);
@@ -335,8 +337,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
335337

336338
// Resample output.
337339
AVSampleFormat sampleFormat = context->sample_fmt;
338-
int channelCount = context->channels;
339-
int channelLayout = context->channel_layout;
340+
int channelCount = context->ch_layout.nb_channels;
340341
int sampleRate = context->sample_rate;
341342
int sampleCount = frame->nb_samples;
342343
int dataSize = av_samples_get_buffer_size(NULL, channelCount, sampleCount,
@@ -346,8 +347,8 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
346347
resampleContext = (SwrContext *)context->opaque;
347348
} else {
348349
resampleContext = swr_alloc();
349-
av_opt_set_int(resampleContext, "in_channel_layout", channelLayout, 0);
350-
av_opt_set_int(resampleContext, "out_channel_layout", channelLayout, 0);
350+
av_opt_set_chlayout(resampleContext, "in_chlayout", &context->ch_layout, 0);
351+
av_opt_set_chlayout(resampleContext, "out_chlayout", &context->ch_layout, 0);
351352
av_opt_set_int(resampleContext, "in_sample_rate", sampleRate, 0);
352353
av_opt_set_int(resampleContext, "out_sample_rate", sampleRate, 0);
353354
av_opt_set_int(resampleContext, "in_sample_fmt", sampleFormat, 0);

0 commit comments

Comments
 (0)