FFmpeg setting OpenMax hardware encoding

Keywords: Mobile codec Linux encoding Android

OpenMax is a unified multimedia framework. ffmpeg supports H264 OpenMax encoding. This paper records how to enable OpenMax encoding.

  • ffmpeg version: 4.0
  • OpenMax header version: 1.2

First download ffmepg, then the header file of OpenMax, and extract the zip of the header file to get Copy the header file to the include of the corresponding platform of NDK, as shown in the figure Then add -- enable OMX at the time of configure

After configure, check whether the following macros in config.h are 1

#define CONFIG_OMX 1
#define CONFIG_H264_OMX_ENCODER 1

After configure, if make reports an error, check the version of the OpenMax header file. There are many fewer header files in the OpenMax 1.0 version

Finally, upload and cross compile the script and test sample of ffmepg

NDK_ROOT=/home/C4/le.zhang/android-ndk-r13b
TOOLCHAIN_DIR=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
SYSROOT=$NDK_ROOT/platforms/android-19/arch-arm
PLATFORM=$SYSROOT
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PREFIX=./build          
function build_one
{
    ./configure \
--prefix=$PREFIX \
--target-os=linux \
--disable-doc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--arch=arm \
--sysroot=$PLATFORM \
--extra-cflags="-I$PLATFORM/usr/include" \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--disable-shared \
--enable-runtime-cpudetect \
--enable-gpl \
--enable-small \
--enable-ffplay \
--enable-cross-compile \
--disable-debug \
--enable-static \
--enable-omx \
--disable-asm \
--disable-symver \
--enable-stripping \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG

    make clean
    make -j8
    make install

    $TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$PLATFORM/usr/lib \
-L$PLATFORM/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
libavdevice/libavdevice.a \
libpostproc/libpostproc.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
}
# arm v7vfp
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
ADDI_CFLAGS="-marm"
build_one
$TOOLCHAIN/bin/arm-linux-androideabi-strip -s $PREFIX/libffmpeg.so

Test sample

#include "libavcodec/avcodec.h"
#include "include/libavformat/avformat.h"

int main(int argc, char **argv)
{
    AVFormatContext *pFormatCtx;
    AVOutputFormat *fmt;
    AVStream *video_st;

    const char* out_file = "/sdcard/ds.264";

    av_register_all();
    //Method1 method 1. Combine several functions
    pFormatCtx = avformat_alloc_context();
    //Guess Format
    fmt = av_guess_format(NULL, out_file, NULL);
    pFormatCtx->oformat = fmt;

    //Method 2. More automatic
    //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
    //fmt = pFormatCtx->oformat;


    //Output Format pay attention to the output path
    if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0)
    {
        printf("Failed to open output file! Output file open failed");
        return -1;
    }

    video_st = avformat_new_stream(pFormatCtx, 0);
    video_st->time_base.num = 1; 
    video_st->time_base.den = 25;  

    if (video_st==NULL)
    {
        return -1;
    }

    AVCodecContext *codec = video_st->codec;

    //pCodecCtx->codec_id =AV_CODEC_ID_HEVC;
    codec->codec_id = fmt->video_codec;
    codec->codec_type = AVMEDIA_TYPE_VIDEO;
    codec->pix_fmt = AV_PIX_FMT_YUV420P;
    codec->width = 640;  
    codec->height = 360;
    codec->time_base.num = 1;  
    codec->time_base.den = 25;  
    codec->bit_rate = 400000;  
    codec->gop_size=250;

    AVCodec *pCodec = avcodec_find_encoder(codec->codec_id);

    printf("codec name : %s\n", pCodec->name);

    return 0;
}

Original author: Lang shuangguo Yang Original link: https://www.jianshu.com/p/61e2c3cbc412

Welcome to my WeChat official account, "code breakout", sharing technology like Python, Java, big data, machine learning, AI, etc., focusing on code farming technology upgrading, workplace breakout, thinking leap, 200 thousand + code farm growth charging station, and growing up with you.

Posted by thebopps on Thu, 16 Apr 2020 09:11:16 -0700