Skip to content

Problems on compile decoder_ffmpeg extension #2071

Closed
@lonewolf73

Description

@lonewolf73

Hello everyone,

I am trying to compile decoder_ffmpeg extension to obtain a libffmpegJNI.so in all architectures or even a libffmpegJNI.aar , to include in my android java project on Ubuntu 20.04LTS platform but I encounter some problems....

  1. Platform : Ubuntu 20.04LTS
  2. CMake : 3.31.4 (I even tried before with version 3.22.6)
  3. I downloaded NDK r26b as suggested by README.md ( 26.1.10909125 ) and I downloaded and installed also the latest r27c ( 27.2.12479018 ) due I encountered during Android Studio "Make Module androidx.media3.lib-decoder-ffmpeg" a problem about iconv library not found...
  4. I installed Opus 1.5.2 from opus-codec.org (I did ./configure , sudo make , sudo make install) to have latest libopus which could decode pure opus audio.
  5. I installed first Ffmpeg following the readme and running git checkout release/6.0 (running ffmpeg -version I obtained a 6.0.2 version compiled by native gcc 9 of Ubuntu 9.4.0-1ubuntu1-20.04.2 ) but once encountering problems, maybe because CMake 3.31.4 is quite new, then I reinstalled latest Ffmpeg 7.1 (ffmpeg version N-118350-ge20ee9f9ae Copyright (c) 2000-2025 the FFmpeg developers) , both versions applying --enable-libopus parameter;
  6. I have set Gradle 8.6 and AGP 8.4.2 on Android Studio
  7. I set ANDROID_ABI to 28 so I set minSdk in gradle files to 28 because having most recent opus and ffmpeg should be more compatible with recent Android app versions
  8. I set in build.gradle of ffmpeg extension as like :
/ Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
apply from: "$gradle.ext.androidxMediaSettingsDir/common_library_config.gradle"

android {
    namespace 'androidx.media3.decoder.ffmpeg'
    compileSdk project.ext.compileSdkVersion
    ndkVersion "26.1.10909125"
    //ndkVersion "27.2.12479018"
    // TODO(Internal: b/372449691): Remove packagingOptions once AGP is updated
    // to version 8.5.1 or higher.
    packagingOptions {
        jniLibs {
            useLegacyPackaging true
        }
    }
    defaultConfig {
        //minSdkVersion project.ext.minSdkVersion
        minSdk project.ext.minSdkVersion
    }
}

// Configure the native build only if ffmpeg is present to avoid gradle sync
// failures if ffmpeg hasn't been built according to the README instructions.
if (project.file('src/main/jni/ffmpeg').exists()) {
    android.externalNativeBuild.cmake.path = 'src/main/jni/CMakeLists.txt'
    // Should match cmake_minimum_required.
    android.externalNativeBuild.cmake.version = '3.31.4'
    //android.externalNativeBuild.cmake.version = '3.21.0+'
}

dependencies {
    implementation project(modulePrefix + 'lib-decoder')
    // TODO(b/203752526): Remove this dependency.
    implementation project(modulePrefix + 'lib-exoplayer')
    implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
    compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
    compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
    testImplementation project(modulePrefix + 'test-utils')
    testImplementation 'org.robolectric:robolectric:' + robolectricVersion
}

In both cases with NDK r26b and r27c if I ran build_ffmpeg.sh ( sudo ./build_ffmpeg.sh "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ANDROID_ABI}" "${ENABLED_DECODERS[@]}" ) with those options (in particular for audio, I had to modify a bit the sh with COMMON_OPTIONS="${COMMON_OPTIONS} --enable-decoder=opus --enable-decoder=libopus --enable-decoder=pcm_alaw" ) due I included libopus in the linked ffmpeg .... it completed but it didn't produced any .so / .aar files... I encountered indeed :

WARNING: /home/user/DevTools/Android/ndk/26.1.10909125/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android28-pkg-config not found, library detection may fail.
WARNING: Disabled libopus_decoder because not all dependencies are satisfied: libopus

so I think those two messages are just warnings but probably they are mandaroty.
I tried to create local toolchain using make_standalone_toolchain.py in ../26.1.10909125/build/tools but once created I searched inside for that pkg-config but wasn't present so for this part , shall I have to modify something somewhere to make it complete the build_ffmpeg.sh creating those .so / .aar file correctly?

Instead if I try to build using ./gradlew lib-decoder-ffmpeg:assembleRelease from media3 root directory ( it installed the gradle 8.6-all ) I get those errors:

> Task :lib-decoder-ffmpeg:processReleaseManifest
package="androidx.media3.decoder.ffmpeg" found in source AndroidManifest.xml: /home/user/projects/media3/libraries/decoder_ffmpeg/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="androidx.media3.decoder.ffmpeg" from the source AndroidManifest.xml: /home/user/projects/media3/libraries/decoder_ffmpeg/src/main/AndroidManifest.xml.

> Task :lib-exoplayer:compileReleaseJavaWithJavac
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:21: error: package android.media.LoudnessCodecController does not exist
import android.media.LoudnessCodecController.OnLoudnessCodecUpdateListener;
                                            ^
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:53: error: cannot find symbol
  @Nullable private android.media.LoudnessCodecController loudnessCodecController;
                                 ^
  symbol:   class LoudnessCodecController
  location: package android.media
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java:685: error: cannot find symbol
        && capabilities.isFeatureSupported(CodecCapabilities.FEATURE_DetachedSurface);
                                                            ^
  symbol:   variable FEATURE_DetachedSurface
  location: class CodecCapabilities
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:81: error: cannot find symbol
    android.media.LoudnessCodecController loudnessCodecController =
                 ^
  symbol:   class LoudnessCodecController
  location: package android.media
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:85: error: cannot find symbol
            new OnLoudnessCodecUpdateListener() {
                ^
  symbol:   class OnLoudnessCodecUpdateListener
  location: class LoudnessCodecController
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:86: error: method does not override or implement a method from a supertype
              @Override
              ^
/home/luigip/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java:82: error: cannot find symbol
        android.media.LoudnessCodecController.create(
                     ^
  symbol:   class LoudnessCodecController
  location: package android.media
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java:58: error: cannot find symbol
          flags |= MediaCodec.CONFIGURE_FLAG_DETACHED_SURFACE;
                             ^
  symbol:   variable CONFIGURE_FLAG_DETACHED_SURFACE
  location: class MediaCodec
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java:200: error: cannot find symbol
    codec.detachOutputSurface();
         ^
  symbol:   method detachOutputSurface()
  location: variable codec of type MediaCodec
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java:126: error: cannot find symbol
          flags |= MediaCodec.CONFIGURE_FLAG_DETACHED_SURFACE;
                             ^
  symbol:   variable CONFIGURE_FLAG_DETACHED_SURFACE
  location: class MediaCodec
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java:322: error: cannot find symbol
    codec.detachOutputSurface();
         ^
  symbol:   method detachOutputSurface()
  location: variable codec of type MediaCodec
warning: unknown enum constant Level.FULL
  reason: class file for com.google.j2objc.annotations.ReflectionSupport$Level not found
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java:1889: error: cannot find symbol
      codecParameters.putInt(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
                                        ^
  symbol:   variable KEY_IMPORTANCE
  location: class MediaFormat
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java:2034: error: cannot find symbol
      mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
                                        ^
  symbol:   variable KEY_IMPORTANCE
  location: class MediaFormat
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:96: error: cannot find symbol
    int transferReason = router.getSystemController().getRoutingSessionInfo().getTransferReason();
                                                                             ^
  symbol:   method getTransferReason()
  location: class RoutingSessionInfo
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:97: error: cannot find symbol
    boolean wasTransferInitiatedBySelf = router.getSystemController().wasTransferInitiatedBySelf();
                                                                     ^
  symbol:   method wasTransferInitiatedBySelf()
  location: class MediaRouter2.RoutingController
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:108: error: cannot find symbol
    int suitabilityStatus = routeInfo.getSuitabilityStatus();
                                     ^
  symbol:   method getSuitabilityStatus()
  location: variable routeInfo of type MediaRoute2Info
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:110: error: cannot find symbol
    if (suitabilityStatus == MediaRoute2Info.SUITABILITY_STATUS_SUITABLE_FOR_MANUAL_TRANSFER) {
                                            ^
  symbol:   variable SUITABILITY_STATUS_SUITABLE_FOR_MANUAL_TRANSFER
  location: class MediaRoute2Info
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:111: error: cannot find symbol
      return (transferReason == RoutingSessionInfo.TRANSFER_REASON_SYSTEM_REQUEST
                                                  ^
  symbol:   variable TRANSFER_REASON_SYSTEM_REQUEST
  location: class RoutingSessionInfo
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:112: error: cannot find symbol
              || transferReason == RoutingSessionInfo.TRANSFER_REASON_APP)
                                                     ^
  symbol:   variable TRANSFER_REASON_APP
  location: class RoutingSessionInfo
/home/luigip/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultSuitableOutputChecker.java:116: error: cannot find symbol
    return suitabilityStatus == MediaRoute2Info.SUITABILITY_STATUS_SUITABLE_FOR_DEFAULT_TRANSFER;
                                               ^
  symbol:   variable SUITABILITY_STATUS_SUITABLE_FOR_DEFAULT_TRANSFER
  location: class MediaRoute2Info
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java:1014: error: cannot find symbol
      mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
                                        ^
  symbol:   variable KEY_IMPORTANCE
  location: class MediaFormat
/home/user/projects/media3/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java:1034: error: cannot find symbol
      codecParameters.putInt(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
                                        ^
  symbol:   variable KEY_IMPORTANCE
  location: class MediaFormat
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
22 errors
1 warning

> Task :lib-exoplayer:compileReleaseJavaWithJavac FAILED

FAILURE: Build failed with an exception.
  • What went wrong:
    Execution failed for task ':lib-exoplayer:compileReleaseJavaWithJavac'.

Compilation failed; see the compiler error output for details.

  • Try:

Run with --info option to get more log output.
Run with --scan to get full insights.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 38s

In this case , does maybe depend from the Gradle version itself and maybe shall I have to upgrade to Gradle 8.9 with AGP 8.7.x since they are anyway supported by Java 17 which is currently installed ?

Thanks in advance to all!
Cheers
Luigi

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions