Skip to content

Commit 04bc48a

Browse files
committed
Migrate to FFmpeg 6.0
-Wl,-Bsymbolic workaround is removed because 6.0 doesn't need it. These changes are also compatible with 5.1 (but not earlier versions) so if 5.1 version is needed then -Wl,-Bsymbolic flag needs to be added back manually.
1 parent 3ed7e56 commit 04bc48a

File tree

4 files changed

+27
-30
lines changed

4 files changed

+27
-30
lines changed

libraries/decoder_ffmpeg/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ FFMPEG_MODULE_PATH="$(pwd)/libraries/decoder_ffmpeg/src/main"
2929
```
3030

3131
* Download the [Android NDK][] and set its location in a shell variable.
32-
This build configuration has been tested on NDK r21.
32+
This build configuration has been tested on NDK r26.
3333

3434
```
3535
NDK_PATH="<path to Android NDK>"
@@ -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
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

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

+22-20
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ static const int AUDIO_DECODER_ERROR_OTHER = -2;
7070
/**
7171
* Returns the AVCodec with the specified name, or NULL if it is not available.
7272
*/
73-
AVCodec *getCodecByName(JNIEnv *env, jstring codecName);
73+
const AVCodec *getCodecByName(JNIEnv *env, jstring codecName);
7474

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

@@ -109,7 +109,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
109109
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
110110
return -1;
111111
}
112-
avcodec_register_all();
113112
return JNI_VERSION_1_6;
114113
}
115114

@@ -128,7 +127,7 @@ LIBRARY_FUNC(jboolean, ffmpegHasDecoder, jstring codecName) {
128127
AUDIO_DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName,
129128
jbyteArray extraData, jboolean outputFloat,
130129
jint rawSampleRate, jint rawChannelCount) {
131-
AVCodec *codec = getCodecByName(env, codecName);
130+
const AVCodec *codec = getCodecByName(env, codecName);
132131
if (!codec) {
133132
LOGE("Codec not found.");
134133
return 0L;
@@ -157,20 +156,25 @@ AUDIO_DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
157156
}
158157
uint8_t *inputBuffer = (uint8_t *)env->GetDirectBufferAddress(inputData);
159158
uint8_t *outputBuffer = (uint8_t *)env->GetDirectBufferAddress(outputData);
160-
AVPacket packet;
161-
av_init_packet(&packet);
162-
packet.data = inputBuffer;
163-
packet.size = inputSize;
164-
return decodePacket((AVCodecContext *)context, &packet, outputBuffer,
159+
AVPacket* packet = av_packet_alloc();
160+
if (!packet) {
161+
LOGE("Failed to allocate packet.");
162+
return -1;
163+
}
164+
packet->data = inputBuffer;
165+
packet->size = inputSize;
166+
const int ret = decodePacket((AVCodecContext *)context, packet, outputBuffer,
165167
outputSize);
168+
av_packet_free(&packet);
169+
return ret;
166170
}
167171

168172
AUDIO_DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
169173
if (!context) {
170174
LOGE("Context must be non-NULL.");
171175
return -1;
172176
}
173-
return ((AVCodecContext *)context)->channels;
177+
return ((AVCodecContext *)context)->ch_layout.nb_channels;
174178
}
175179

176180
AUDIO_DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
@@ -193,7 +197,7 @@ AUDIO_DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
193197
// Release and recreate the context if the codec is TrueHD.
194198
// TODO: Figure out why flushing doesn't work for this codec.
195199
releaseContext(context);
196-
AVCodec *codec = avcodec_find_decoder(codecId);
200+
const AVCodec *codec = avcodec_find_decoder(codecId);
197201
if (!codec) {
198202
LOGE("Unexpected error finding codec %d.", codecId);
199203
return 0L;
@@ -215,17 +219,17 @@ AUDIO_DECODER_FUNC(void, ffmpegRelease, jlong context) {
215219
}
216220
}
217221

218-
AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
222+
const AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
219223
if (!codecName) {
220224
return NULL;
221225
}
222226
const char *codecNameChars = env->GetStringUTFChars(codecName, NULL);
223-
AVCodec *codec = avcodec_find_decoder_by_name(codecNameChars);
227+
const AVCodec *codec = avcodec_find_decoder_by_name(codecNameChars);
224228
env->ReleaseStringUTFChars(codecName, codecNameChars);
225229
return codec;
226230
}
227231

228-
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
232+
AVCodecContext *createContext(JNIEnv *env, const AVCodec *codec, jbyteArray extraData,
229233
jboolean outputFloat, jint rawSampleRate,
230234
jint rawChannelCount) {
231235
AVCodecContext *context = avcodec_alloc_context3(codec);
@@ -250,8 +254,7 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
250254
if (context->codec_id == AV_CODEC_ID_PCM_MULAW ||
251255
context->codec_id == AV_CODEC_ID_PCM_ALAW) {
252256
context->sample_rate = rawSampleRate;
253-
context->channels = rawChannelCount;
254-
context->channel_layout = av_get_default_channel_layout(rawChannelCount);
257+
av_channel_layout_default(&context->ch_layout, rawChannelCount);
255258
}
256259
context->err_recognition = AV_EF_IGNORE_ERR;
257260
int result = avcodec_open2(context, codec, NULL);
@@ -293,8 +296,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
293296

294297
// Resample output.
295298
AVSampleFormat sampleFormat = context->sample_fmt;
296-
int channelCount = context->channels;
297-
int channelLayout = context->channel_layout;
299+
int channelCount = context->ch_layout.nb_channels;
298300
int sampleRate = context->sample_rate;
299301
int sampleCount = frame->nb_samples;
300302
int dataSize = av_samples_get_buffer_size(NULL, channelCount, sampleCount,
@@ -304,8 +306,8 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
304306
resampleContext = (SwrContext *)context->opaque;
305307
} else {
306308
resampleContext = swr_alloc();
307-
av_opt_set_int(resampleContext, "in_channel_layout", channelLayout, 0);
308-
av_opt_set_int(resampleContext, "out_channel_layout", channelLayout, 0);
309+
av_opt_set_chlayout(resampleContext, "in_channel_layout", &context->ch_layout, 0);
310+
av_opt_set_chlayout(resampleContext, "out_channel_layout", &context->ch_layout, 0);
309311
av_opt_set_int(resampleContext, "in_sample_rate", sampleRate, 0);
310312
av_opt_set_int(resampleContext, "out_sample_rate", sampleRate, 0);
311313
av_opt_set_int(resampleContext, "in_sample_fmt", sampleFormat, 0);

0 commit comments

Comments
 (0)