avcodec_find_encoder(AV_CODEC_ID_H264) returns null

Monjura Rumi picture Monjura Rumi · Apr 4, 2013 · Viewed 7.2k times · Source

I am building an android application which will encode image captured from camera preview and later decode it. I am using ffmpeg library to encode and decode. To build static library with x264 I have used this tutorial. http://dl.dropbox.com/u/22605641/ffmpeg_android/main.html. As a source code of ffmpeg if I use the one downloaded from the link given in tutorial I can built it but can't build library if i use source code downloaded from here git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg. I have built library in ubuntu and using it in windows 7 in Eclipse. As I need only h264 encoder and decoder I have used following code for ffmpeg, slightly modified from tutorial.

#!/bin/bash

NDK=~/Documents/android-ndk-r8e
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PREFIX=/home/android-ffmpeg

function build_one
{
    ./configure --target-os=linux --prefix=$PREFIX \
    --enable-cross-compile \
    --enable-runtime-cpudetect \
    --disable-asm \
    --arch=arm \
    --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
    --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
    --disable-stripping \
    --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
    --sysroot=$PLATFORM \
    --enable-nonfree \
    --enable-version3 \
    --disable-everything \
    --enable-gpl \
    --disable-doc \
    --enable-avresample \
    --disable-ffplay \
    --disable-ffserver \
    --enable-ffmpeg \
    --disable-ffprobe \
    --enable-avcodec \
    --enable-libx264 \
    --enable-encoder=libx264 \
    --enable-encoder=libx264rgb \
    --enable-decoder=h263 \
    --enable-decoder=h264 \
    --enable-decoder=svq3 \   
    --enable-zlib \
    --enable-gpl \
    --enable-pic \
    --disable-devices \
    --disable-avdevice \
    --extra-cflags="-I/home/android-ffmpeg/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
    --extra-ldflags="-L/home/android-ffmpeg/lib"
make -j4 install
$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$PREFIX/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a libavresample/libavresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lx264 --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
}

build_one

After building library I have been able to build android ndk. A little part of my JNI code is here.

JNIEXPORT jint JNICALL Java_com_example_testjava_TestjniActivity_initencoder(JNIEnv* env,jobject obj){

    av_register_all();
    avcodec_register_all();
    codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!codec) {
      __android_log_write(ANDROID_LOG_INFO, "debug", "not found");                
       return -1;
    }
.
.
.
}

When I run my java source code that calls initencoder() I get -1 as return value and logcat prints "not found". That means avcodec_find_encoder() returns null and if condition is being ok. I don't know what's wrong. Why this function is returning null? I have searched a lot but did not find any solution that could guide me to right direction. some says to use avcodec_init(). But ndk-build command fails and shows error saying undefined reference to 'avcodec_init()'. I have started with library build because I thought may be I am doing wrong from the first stage. Did I make any mistake in library building like not enabling things that I should? Please help me here. This is kind of urgent for me.

Answer

TastyCatFood picture TastyCatFood · Feb 28, 2017

Problem: avcodec_find_encoder returns NULL;

Possible causes:

  1. libx264 something went wrong during compile or configuration process.
  2. libx264 has not been packaged into apk or loaded properly.

My case, it was both. I had "--enable-libx264" in configuration option, but had not provided paths to android compatible libx264 library and include directories, so the library had been compiled without x264 support. Hope this will save someone's time.

Solution

After compiling x264 with the appropriate toolchain and making them available to ffmpeg at ffmpeg compilation time by setting --extracflags and placing self-compiled x264 libs and includes in jni folder, it stopped returning NULL at least.

My ffmpeg build script:

NDK=$HOME/Android/Sdk/ndk-bundle
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$HOME/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CPREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-

CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"

ADDI_CFLAGS="$ADDI_CFLAGS -I${NDK}/sources/x264 -I${NDK}/sources/x264/android/arm/include -L${NDK}/sources/x264/android/arm/lib -DANDROID -I${NDK}/sources/cxx-stl/system/include"
# -mfloat-abi=softfp -mfpu=neon"

ADDI_LDFLAGS="$ADDI_LDFLAGS -L${NDK}/sources/x264/android/arm/lib"
#--extra-cxxflags='-Wno-multichar -fno-exceptions -fno-rtti'

function build_it {
./configure \
    --prefix=$PREFIX    \
    --disable-static    \
    --enable-shared     \
    --disable-doc       \
    --disable-ffmpeg    \
    --disable-ffplay    \
    --disable-ffprobe   \
    --disable-ffserver  \
    --disable-avdevice  \
    --disable-doc       \
    --disable-symver    \
    --cross-prefix=$CPREFIX \
    --target-os=linux   \
    --arch=arm      \
    --enable-cross-compile  \
    --enable-gpl        \
    --enable-libx264    \
    --sysroot=$SYSROOT  \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG


    make clean
    make
    make install

    echo "build done run make install"
}


build_it

My x264 build script:

#Android related

NDK=$HOME/Android/Sdk/ndk-bundle
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$HOME/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CPREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"

export PATH="$PATH:$TOOLCHAIN/bin"

#PKG_CONFIG_PATH="$HOME/Android/Sdk/ndk-bundle/sources/FFmpeg/lib/pkgconfig" 

function build_it {
./configure \
    --prefix=$PREFIX \
    --bindir=$HOME/Android/Sdk/ndk-bundle/sources/bin \
    --enable-static \
    --host=arm-linux \
    --enable-pic \
    --sysroot=$SYSROOT \
    --cross-prefix=arm-linux-androideabi- \
    --enable-shared \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
}
build_it
make
make install