當前位置:首頁 » 編程軟體 » 編譯ffmpegndk

編譯ffmpegndk

發布時間: 2023-08-27 03:33:48

1. Ubuntu 環境 編譯 ffmpeg移植android 的問題!

到FFmpeg官方網站http://www.ffmpeg.org/上去下載源代碼,這里下載的源代碼是最權威的。進入官網之後,選擇」Download」進入下載頁面,截止2014年3月28日止,最新的發布的穩定版本為FFmpeg2.2,代號」Muybridge」。選擇該下方的」Downloadgzip tarball」進行下載,下載後的文件名為ffmpeg-2.2.tar.gz,大約8.3M。
第二步:在linux環境下編譯FFmpeg
在Windows平台可以採用VMplayer虛擬機上安裝ubuntu的方式,本人也是採用這種方式。
本文以/home/dennis為根目錄進行操作和說明:
將ffmpeg-2.2.tar.gz拷貝至根目錄,然後執行如下解壓命令將其解壓:
$tar zxf ffmpeg-2.2.tar.gz
解壓後將得到/home/dennis/ffmpeg-2.2目錄。

2. 記一次FFmpeg的編譯過程的坑

參考文章: iOS開發 - 超詳細集成 FFmpeg 步驟

                  iOS集成FFmpeg及視頻格式轉碼

以下是在編譯過程孫拍余遇到的問題:

1.編譯出現以下錯誤信息.

xcrun -sdk iphoneos clang is unable to create an executable file.

C compiler test failed.

Ifyou think configure made a mistake, make sure you are using the latestversion from Git.Ifthe latest version fails, report the problem to [email protected] mailinglistorIRC#ffmpeg on irc.freenode.net.Includethe log file"config.log"proced by configureasthis will helpsolve the problem.

問賀橡題鏈接: https://github.com/kewlbear/FFmpeg-iOS-build-script/issues/119

這時只需執行以下命令即可:

sudo xcode-select --switch /Applications/Xcode.app

2.'libavcodec/avcodec.h' file not found 說是找不到

因該是 headerSearchPath 裡面的路徑添加的不對.

一種寫法:

$(SRCROOT)/FFmpeg_iOS/FFmpeg/include

這個寫法  我這邊 不得行.

第二中寫法:

$(SRCROOT)/$(PRODUCT_NAME)/FFmpeg-iOS/include

我的項目里則滾面這個可以使用

3. 如何用Android NDK編譯FFmpeg

一、安裝cygwin、配置ndk和下載ffmpeg源碼

這步就不說了,網上很多教程,再次聲明本教程只針對ndk R4這個版本。需要說明的是,本人在cygwin安裝路徑下的.bash_profile文件中指定的NDK路徑如下所示。因為本人裝了好幾個NDK,因此後面的R4隻是個標示。

NDK_R4=/cygdrive/d/android-ndk-r4
export NDK_R4

二、編譯前准備和編譯

1、因為R4這個NDK比較舊,交叉編譯的時候需要在一個Android環境中,那簡單,創建一個Android空項目,把整個項目拷出來,在項目下建立一個文件夾jni,把ffmpeg0.6.6的源碼拷進去。左圖,HelloJni就是我新建的一個項目,Android.mk這時候你還沒有,先不用管。右圖ffmpeg-0.6.6文件夾的內容要跟我一樣,直接就是代碼。我這里的ffmpeg_cywin這個文件夾是隨便建的,放哪裡無所謂的。

2、在ffmpeg-0.6.6下建立一個文件config.sh,內容如下所示。需要注意的是,unix下的換行符和windows下是不一樣,如果直接拷貝到windows下的記事本,後面執行這個config.sh的時候會出問題,這里我用的是notepad++編輯的,在編輯->檔案格式轉換->轉換為UNIX格式。(注意,後面的所有的Android.mk的編輯都有此要求)。

簡單說一下這個config.sh,PREBUILT和PLATFORM根據你安裝ndk的位置而不同,config.sh其實是一個腳本,執行這個腳本的時候又調用了另外一個腳本configure,configure主要是根據編譯選項(下面enable disable那些),生成相應的編譯配置,就是說你想要編譯ffmpeg什麼模塊就自己定製編譯選項的內容。基本上這個文件只要修改一下PREBUILT和PLATFORM就行,其他都不用改。

#!/bin/bash
export PREBUILT=D://android-ndk-r4/build/prebuilt/windows/arm-eabi-4.4.0
export PLATFORM=D://android-ndk-r4/build/platforms/android-8/arch-arm
./configure --target-os=linux \
--arch=arm \
--enable-version3 \
--enable-gpl \
--enable-nonfree \
--disable-stripping \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffserver \
--disable-ffprobe \
--disable-encoders \
--disable-muxers \
--disable-devices \
--disable-protocols \
--enable-protocol=file \
--enable-avfilter \
--disable-network \
--disable-mpegaudio-hp \
--disable-avdevice \
--enable-cross-compile \
--cc=$PREBUILT/bin/arm-eabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-eabi- \
--nm=$PREBUILT/bin/arm-eabi-nm \
--extra-cflags="-fPIC -DANDROID" \
--disable-asm \
--enable-neon \
--enable-armv5te \
--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"
3、修改configure文件,找到下圖的內容,修改成我這樣,這個是用來存放執行腳本過程的臨時文件的,我這里用的是D://NDK,你可以設置其他地方,但是要先創建好這個文件夾,放哪裡無所謂的。

4、然後在cywin中進入ffmpeg0.6.6文件夾,執行chmod -x config.sh,然後執行./config,此過程需要一定的時間。如果這一步出現問題,很有可能是你config.sh中的PREBUILT和PLATFORM的路徑設置不對,或者是你拷貝內容到config.sh的時候沒有在UNIX格式下。執行完如下圖所示。

5、在ffmpeg-0.6.6下會生成一個config.h文件,編輯它,找到#define restrict restrict這一行,把它改成#define restrict

6、在libavutil/libm.h下,把所有static的方法注釋掉或者直接刪掉。

7、修改libavcodec,libavfilter,libavformat,libavutil,libpostproc和libswscale目錄的MakeFile文件,每個文件中,刪除語句

include $( SUBDIR ) ../config.mak 和 include $ (SUBDIR) .. / subdir.mak。

libavcodec下的makefile中搜索inverse.o,把它所在的那一行刪掉,要不編譯的時候會沖突。

8、在ffmpeg-0.6.6文件夾下,創建av.mk文件(UNIX格式),內容如下:

#LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak
include $(LOCAL_PATH)/../config.mak

OBJS :=
OBJS-yes :=
MMX-OBJS-yes :=
include $(LOCAL_PATH)/Makefile

# collect objects
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)

FFNAME := lib$(NAME)
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))
FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign
FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"

ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))

ifneq ($(ALL_S_FILES),)
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))
else
C_OBJS := $(OBJS)
S_OBJS :=
endif

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))
S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

9、在jni文件夾下,創建Android.mk(UNIX格式),內容如下:
include $(all-subdir-makefiles)

10、在ffmpeg-0.6.6文件夾下,創建Android.mk,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

11、在ffmpeg-0.6.6\libavformat下,創建Android.mk,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)

12、在ffmpeg-0.6.6\libavcodec下,創建Android.mk,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)

13、在ffmpeg-0.6.6\libavfilter、libavutil、libpostproc和libswscale下,創建Android.mk,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
14、然後在jni目錄下,運行$NDK_R4/ndk-build -B,這里的命令需要根據你自己的情況修改,然後就開始編譯了。過程需要10來分鍾,成功之後,會在libs下生產libffmpeg.so。如果編譯出來的libffmpeg.so只有1.5k,得如下修改一下NDK,再重新編譯。

把下面紅色部分加到NDK的build/core/build-binary.mk里:
LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
LOCAL_STATIC_WHOLE_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
static_whole_libraries := $(call map,static-library-path,$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
$(call mole-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_LIBRARIES))
$(call mole-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
$(LOCAL_BUILT_MODULE): $(static_libraries) $(static_whole_libraries) $(shared_libraries)
...
$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(static_whole_libraries)
接著再將最外層ffmpeg/Android.mk裡面的LOCAL_STATIC_LIBRARIES改成LOCAL_STATIC_WHOLE_LIBRARIES

4. 如何用Android NDK編譯FFmpeg

android的NDK開發需要在linux下進行:

  1. 因為需要把C/C++編寫的代碼生成能在arm上運行的.so文件,這就需要用到交叉編譯環境,而交叉編譯需要在linux系統下才能完成。

  2. 安裝android-ndk開發包,這個開發包可以在google android 官網下載: 通過這個開發包的工具才能將android jni 的C/C++的代碼編譯成庫

  3. android應用程序開發環境: 包括eclipse、java、 android sdk、 adt等。

NDK編譯步驟:

a.選擇ndk自帶的例子hello-jni,我的位於E:android-ndk-r5sampleshello-jni(根據具體的安裝位置而定) 。

b.運行cygwin,輸入命令cd /cygdrive/e/android-ndk-r5/samples/hello-jni,進入到E:android-ndk-r5sampleshello-jni目錄。

c.輸入$NDK/ndk-build,執行成功後,它會自動生成一個libs目錄,把編譯生成的.so文件放在裡面。($NDK是調用我們之前配置好的環境變數,ndk-build是調用ndk的編譯程序)

d.此時去hello-jni的libs目錄下看有沒有生成的.so文件,如果有,ndk就運行正常啦。

5. 如何使用ndk編譯ffmpeg靜態庫

如何使用ndk為ffmpeg編譯rtmp+polarssl靜態庫?這個問題花了我整整一天時間。其中遇到很多小問題,這里記錄一下,方便自己也方便其他人。

1、編譯polarssl,查看其Readme文件即可,不需要configure,只需要make時帶上必要的參數即可,不過要記得在每一次執行make命令時都帶上CC的參數(指向你的arm gcc),因為我試過在make install時沒有帶上CC的參數,雖然能編譯出polarssl但是未能正確被rtmp引用到。

2、因為前面我用的polarssl是當前最新(1.3.7)版本,而librtmp使用的好像是polarssl1.0.0以下版本的api,所以需要修改rtmp部分源碼,讓其調用新版polarssl的api,這里的修改可以參照《Migrating from PolarSSL-1.2 to the PolarSSL 1.3 branch》和《[rtmpmp] branch master updated. a312ac7 Fix compat with PolarSSL >= 1.1.0》。

3、出現 undefined reference to `havege_random』錯誤,這里是因為polarssl默認關閉了havege模塊,需要你手動開啟,主要就是修改include/polarssl/config.h,去掉POLARSSL_HAVEGE_C前的注釋,也就是要定義POLARSSL_HAVEGE_C,如下:
#define POLARSSL_HAVEGE_C

4、在編譯出上面兩個庫之後,可以開始編譯ffmpeg(2.1.1版本)了,如果遇到下面的問題 check_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
ERROR: librtmp not found
這里有三種解決方法:
第一種,因為是網路上傳播最多的,算是比較簡便的方法,就是修改ffmpeg的configure,將以下一行:
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
改為:
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Socket -lrtmp -lpolarssl -lz
或者直接注釋掉&& *** 部分,然後再自己加上librtmp的庫路徑也行

第二種,(比較推薦,因為解決了這個會順帶解決大部分找不到庫的錯誤!)因為這里使用了pkg-config工具查找庫,而這個工具ndk並沒有附帶提供,而出現check_pkg_config相關錯誤的話,只要稍加註意,會發現在使用configure配置ffmpeg的交叉編譯時,已經有相應的pkg-config不存在的警告了。我對這個工具不熟悉,所以我只是簡單地加上了一個軟鏈接到系統的pkg-config,如下:
ln -s /usr/bin/pkg-config /home/cidy0106/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config
這個時候重新configure的話可能會出現找不到polarssl庫的錯誤提示,需要修改一下librtmp安裝目錄里的librtmp.pc,把以下內容:
Libs: -L${libdir} -lrtmp -lz
改為:
Libs: -L${libdir} -lrtmp -lz -lpolarssl

至此,就可以正確編譯出ffmpeg了
轉載

6. ffmpeg 64位編譯腳本

NDK版本:android-ndk-r14b

ffmpeg版本:4.2.4 / 4.4

Ubuntu版本:15.5

#!/bin/bash

  NDK=/home/linrendi/Desktop/Compile/android-ndk-r14b

  PLATFORM=$NDK/platforms/android-21/arch-arm64

  TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64

  PREFIX=/home/linrendi/Desktop/ffmpeg64

  CPU=armv8-a

  function build_one

  {

      ./configure \

  --prefix=$PREFIX \

  --target-os=android \

  --disable-doc \

  --cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \

  --arch=arm64 \

  --cpu=$CPU \

  --disable-asm \

  --sysroot=$PLATFORM \

  --extra-cflags="-I$PLATFORM/usr/include" \

  --cc=$TOOLCHAIN/bin/aarch64-linux-android-gcc \

  --nm=$TOOLCHAIN/bin/aarch64-linux-android-nm \

  --disable-shared --enable-static \

  --enable-small --disable-debug \

  --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-symver \

  --enable-neon  --enable-pthreads \

  --disable-devices --disable-encoders \

  --enable-hwaccels --enable-jni --enable-mediacodec \

  --enable-encoder=aac \

  --enable-decoder=h264_mediacodec \

  --enable-hwaccel=h264_mediacodec \

  --enable-encoder=mjpeg \

  --enable-encoder=ljpeg --enable-encoder=jpeg2000 --enable-encoder=jpegls \

  --enable-muxer=mp4 --enable-muxer=mjpeg \

  --enable-runtime-cpudetect \

    make clean

    make -j4

    make install

    $TOOLCHAIN/bin/aarch64-linux-android-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 \

    -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \

    $TOOLCHAIN/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a

  }

  build_one

熱點內容
phpip2long 發布:2024-11-20 19:16:47 瀏覽:948
編程貓登錄代 發布:2024-11-20 19:04:29 瀏覽:351
我的世界伺服器刷怪指令 發布:2024-11-20 19:00:22 瀏覽:829
裝修配置專員是什麼的 發布:2024-11-20 18:55:02 瀏覽:620
怎麼破解蘋果手機6密碼怎麼辦 發布:2024-11-20 18:52:25 瀏覽:405
解密數字編程 發布:2024-11-20 18:50:55 瀏覽:714
python字典生成 發布:2024-11-20 18:46:41 瀏覽:22
內網伺服器怎麼免費獲得 發布:2024-11-20 18:25:34 瀏覽:73
php不重復隨機數 發布:2024-11-20 18:25:30 瀏覽:930
職業病上傳 發布:2024-11-20 18:23:27 瀏覽:5