天天看点

FFMPEGFFMPEG系列笔记记录前言一、FFMPEG是什么二、怎么使用总结

FFMPEG系列笔记记录

第一章 FFMPEG编译

FFMPEG编译

  • FFMPEG系列笔记记录
  • 前言
  • 一、FFMPEG是什么
  • 二、怎么使用
    • 1.环境准备
      • 1.1源码下载
      • 1.1NDK环境下载
    • 2.源码编译
    • 3.引用
  • 总结

前言

最近想深入了解一下FFMPEG开源库的使用,于是着手从头弄一个轮子,然后按照自己的想法去造。

一、FFMPEG是什么

这个就不解释了,很强大的视频编解码库,初学者就了解到这么多了,很多内容我准备一遍探索一遍去完善笔记。

二、怎么使用

1.环境准备

由于编译好的FFMPEG准备在Android终端上使用,所以准备用NDK编译方式去编译,我这用的是linux编译环境,然后运行的Android终端是Android-9。

1.1源码下载

贴一个官网链接:http://www.ffmpeg.org/olddownload.html ,这里可以去找想要的版本

FFMPEGFFMPEG系列笔记记录前言一、FFMPEG是什么二、怎么使用总结

1.1NDK环境下载

这里使用的NDK环境是android-ndk-r11,NDK环境安装可以参考一下网上的文章,我这里因为是现成的,就没有安装了。=。=

忘记了,还有一个不错的编解码库openh264,记得下载这个不然会报错。

PS:不同的NDK环境,编译FFMPEG的时候,会因为FFMPEG的版本变动而出现报错,需要手动解决。避免踩坑,建议使用已经成功编译的匹配版本,除非有些功能必须使用。

2.源码编译

首先需要编译FFMPEG,根据编译环境,目标机器架构,以及NDK,需要进行配置。FFMPEG有一个配置脚本configure用来根据不同的环境需求进行配置,大概情况就是配置完之后编译,然后安装。这里用脚本来一次搞定。

#!/bin/bash
NDK=/opt/android_build/android-ndk-r11
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CFLAGS="-O3 -Wall -DANDROID -DNDEBUG -nostdlib"
EXTRA_CFLAGS="-march=armv7-a -mfpu=neon \
              -mfloat-abi=softfp "
OPTIMIZE_CFLAGS="-marm"
CPU=arm
PREFIX=****/FFmpeg-2.7.2-use-zip/android-21

#ADDI_CFLAGS="-I/home/ndk/arm/x264/include"
#ADDI_LDFLAGS="-L/home/ndk/arm/x264/lib"
ADDI_CFLAGS="-I/home/hzg/mypath/simpleexample_ffmpeg/openh264/include"
ADDI_LDFLAGS="-L/home/hzg/mypath/simpleexample_ffmpeg/openh264/lib"
#--disable-demuxers**
#**--disable-decoders**
#**--disable-devices**
#**--disable-filters**
#**--enable-decoder=h264**
#**--enable-decoder=mp3***
#**--enable-demuxer=mpegts**

function build_one
{
#make distclean
./configure \
--prefix=$PREFIX \
--enable-shared \
--enable-nonfree \
--enable-gpl \
--enable-swscale \
--enable-asm \
--enable-yasm \
--enable-stripping \
--disable-libx264 \
--enable-libopenh264 \
--enable-demuxers \
--enable-decoders \
--disable-yasm \
--disable-devices \
--disable-filters \
--disable-programs \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--disable-debug \
--disable-network \
--disable-hwaccels \
--disable-indevs \
--disable-outdevs \
--disable-iconv \
--enable-fast-unaligned \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--cpu=armv7-a \
--enable-cross-compile \
--sysroot=$SYSROOT  \
--extra-cflags="-march=armv7-a -mfpu=neon -mfloat-abi=softfp -DFF_OPT_ZIP -DFF_OPT_LESSDIRTY -DWITH_CHANGE_BY_ZTE -DRECTIFY_YUV422 -DPAL_ENCODE -O0 $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"
#$ADDITIONAL_CONFIGURE_FLAG

#--extra-cflags="-Os -fpic -mfpu noen\
#--extra-cflags="-Os -fpic -mfpu neon\
#--extra-cflags="-Os -mfpu neon -fPIC -DANDROID -mfpu=neon -mfloat-abi=softfp ADDI_CFLAGS "
make clean
make -j32
make /home/hzg/mypath/simpleexample_ffmpeg/FFmpeg-2.7.2-use-zip/android-21 install
}
build_one

           

在configure文件配置一下如下库名

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
           

编译完FFMPEG之后,会在目标目录下生成对应的库,头文件,以及执行文件。

头文件:

./build/include/libavutil/log.h
./build/include/libavutil/downmix_info.h
./build/include/libavutil/error.h
./build/include/libavutil/ripemd.h
./build/include/libavutil/fifo.h
./build/include/libavutil/imgutils.h
./build/include/libavutil/cpu.h
./build/include/libavutil/base64.h
./build/include/libavutil/random_seed.h
./build/include/libavutil/intreadwrite.h
           

库:

./android-21/lib/libavcodec-56.so
./android-21/lib/libswresample.so
./android-21/lib/libpostproc-53.so
./android-21/lib/libavcodec.so
./android-21/lib/libavutil-54.so
./android-21/lib/libavfilter.so
./android-21/lib/libpostproc.so
./android-21/lib/libswscale.so
./android-21/lib/libavformat.so
./android-21/lib/libavfilter-5.so
./android-21/lib/libavformat-56.so
./android-21/lib/libswresample-1.so
./android-21/lib/libswscale-3.so
./android-21/lib/libavutil.so
           

执行程序

ffmpeg
ffprobe
           

3.引用

Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
#include Prebuild_Android.mk
LOCAL_SRC_FILES:= \
        main.c
#       simpl.c \

BUILD_PATH:=$(LOCAL_PATH)/FFmpeg-2.7.2-use-zip/android-21

LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)/FFmpeg-2.7.2-use-zip/build/include \
        $(LOCAL_PATH)/openh264/include \

LOCAL_CFLAGS :=
LOCAL_CFLAGS += -fPIC -Wformat-security
LOCAL_CFLAGS += $(CFLAGS) -g -O2 -DENABLE_FFMPEG=1

LOCAL_LDFLAGS :=
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libavformat.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libavfilter.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libpostproc.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libswscale.a
LOCAL_LDFLAGS += $(LOCAL_PATH)/FFmpeg-2.7.2-use-zip/build/lib/libavdevice.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libavcodec.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libavformat.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libavutil.a
LOCAL_LDFLAGS += $(BUILD_PATH)/lib/libswresample.a
LOCAL_LDFLAGS += $(LOCAL_PATH)/openh264/libopenh264.a

#数学库和libz压缩库依赖
#LOCAL_LDFLAGS += -lswresample
LOCAL_LDFLAGS += -lm -lz

LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_MODULE:= test_ffmpeg
include $(BUILD_EXECUTABLE)
include Prebuild_Android.mk
           

总结

中途遇到的报错记录一下

链接报错

./FFmpeg-2.7.2-use-zip/build/lib/libavformat.a(id3v2.o):id3v2.c:function id3v2_parse: error: undefined reference to 'uncompress'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decompress.isra.3: error: undefined reference to 'inflateInit_'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decompress.isra.3: error: undefined reference to 'inflate'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decompress.isra.3: error: undefined reference to 'inflateEnd'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decompress.isra.3: error: undefined reference to 'inflateEnd'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decoder_decode_begin: error: undefined reference to 'zlibVersion'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decoder_decode_begin: error: undefined reference to 'zlibVersion'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decoder_decode_begin: error: undefined reference to 'zlibVersion'
./FFmpeg-2.7.2-use-zip/build/lib/libavcodec.a(zip_decoder.o):zip_decoder.c:function zip_decoder_decode_begin: error: undefined reference to 'zlibVersion'

           

解决办法

It’s because libavcodec includes some math and zlib headers, so you must link to the respective libraries as well

因为使用了math和zlib库,所以编译的时候需要添加相应的库

运行报错

CANNOT LINK EXECUTABLE DEPENDENCIES: library "libavformat.so.56" not found
           

解决办法

提示找不到libavformat.so.56,这里.56是对应的库版本号,编译的时候,有参照前人的办法,在configure文件中将编译出来的库名字做修改了,但是会出现.a,.so,.so.56,这里我引用动态库都会报错这个,引用静态库就可以了。只是说找到解决办法了,深入原因有大佬清楚可以一起讨论

继续阅读