Ubuntu下用NDK編譯移植FFmpeg 2.0(配置最新版x264)到Android平臺
將x264配置到ffmpeg中需要先編譯x264,生成靜態庫或動態庫。因為264的靜態庫本身不大(我編譯完成後是1.1M)且考慮到平臺移植問題,這裡選擇的是編譯生成靜態庫。
準備,新建工作空間
(1)建立總目錄FFmpeg-Android
eg: mkdir workspace --> cd workspace --> mkdir FFmpeg-Android --> cd FFmpeg-Android
(2)建立儲存x264靜態庫的目錄 android-x264
(在FFmpeg-Android目錄下)mkdir 264 --> cd 264
1、編譯x264
(1)去官網:
(2)編寫指令碼檔案:
export NDK=$NDK_HOME
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt
export PLATFORM=$NDK/platforms/android-19/arch-arm
export PREFIX=../../android-x264
./configure --prefix=$PREFIX \
--enable-static \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM
注意:這裡涉及到路徑的變數需要根據你們自己的情況來調整。
PREBUILT 變數儲存的是NDK交叉編譯鏈的路徑,
PLATFORM 變數儲存的是NDK進行連結時查詢庫檔案的路徑(arch-arm目錄下儲存的是各種andorid平臺下的c庫標頭檔案和靜態以及動態庫)
PREFIX 變數儲存的是編譯生成的靜態庫儲存的路徑
(3)執行指令碼
(4)執行完剛才的指令碼後,會在當前目錄生成配置檔案,這裡還需要修改以下幾個檔案,原因是:編譯成功後在eclipse下執行會出現 "cannot locate symbol 'log2f' " 的錯誤
修改1、config.h
---- #define HAVE_LOG2F 1
+++#define HAVE_LOG2F 0
修改2、encoder/encoder.c 、 encoder/ratecontrol.c 、encoder/analyse.c 、encoder/set.c
在檔案開頭處新增
+++ #include
+++ //
(5)在當前目錄下執行: make , make install
完成後,就可以在FFmpeg-Android的android-x264目錄下生成標頭檔案和靜態庫檔案了,至此,x264編譯完成。
2、編譯FFmpeg 2.0 ,下載地址:
(1)將壓縮包解壓縮到FFmpeg-Android的根目錄下
(2)編寫指令碼,這裡將配置和編譯過程分成兩個指令碼來寫,主要是配置指令碼完成後,還要手動的去修改ffmpeg目錄下的config.h檔案
配置指令碼:
#!/bin/bash
DEST=`pwd`/build/ffmpeg && rm -rf $DEST
SOURCE=`pwd`/ffmpeg
if [ -d ffmpeg ]; then
cd ffmpeg
else
echo "can not find ffmpeg source code"
exit 1
fi
if [ "$PIPESTATUS" != "0" ] ; then
echo "error in FFmpeg-Android.sh : 14 "
fi
TOOLCHAIN=/tmp/vplayer
SYSROOT=$TOOLCHAIN/sysroot/
$NDK_HOME/build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=$TOOLCHAIN
export PATH=$TOOLCHAIN/bin:$PATH
export CC="arm-linux-androideabi-gcc"
export LD=arm-linux-androideabi-ld
export AR=arm-linux-androideabi-ar
#CFLAGS="-O3 -Wall -mthumb -pipe -fpic -fasm \
# -finline-limit=300 -ffast-math \
# -fstrict-aliasing \
# -fmodulo-sched -fmodulo-sched-allow-regmoves \
# -Wno-psabi -Wa,--noexecstack \
# -DANDROID -DNDEBUG"
CFLAGS="-Os -fPIC -marm"
FFMPEG_FLAGS="--target-os=linux \
--arch=arm \
--sysroot=$SYSROOT \
--enable-cross-compile \
--cross-prefix=arm-linux-androideabi- \
--enable-shared \
--enable-static \
--disable-symver \
--disable-doc \
--disable-ffplay \
--disable-ffmpeg \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-avfilter \
--disable-filters \
--disable-devices \
--disable-pthreads \
--disable-everything \
--enable-gpl \
--enable-muxers \
--enable-encoders \
--enable-protocols \
--enable-parsers \
--enable-demuxers \
--enable-decoders \
--enable-bsfs \
--enable-network \
--enable-swscale \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-muxer=h264 \
--enable-demuxer=h264 \
--disable-demuxer=sbg \
--disable-demuxer=dts \
--disable-parser=dca \
--disable-decoder=dca \
--extra-libs=-lx264 \
--enable-asm \
--enable-version3"
VERSION=armv7
cd $SOURCE
EXTRA_CFLAGS="-I../android-x264/include -march=armv7-a"
EXTRA_LDFLAGS="-L../android-x264/lib"
PREFIX="$DEST/$VERSION" && mkdir -p $PREFIX
FFMPEG_FLAGS="$FFMPEG_FLAGS --prefix=$PREFIX"
sh ./configure $FFMPEG_FLAGS --extra-cflags="$CFLAGS $EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" | tee $PREFIX/configuration.txt
if [ "$?" = "0" ] ; then
echo "./configure success in shell-script"
else
echo "./configure erroe in shell-script"
exit 1
fi
cp config.* $PREFIX
我們編譯ffmpeg的過程是這樣的,將交叉編譯鏈拷貝整個拷貝一份到系統的臨時目錄下/tmp的vplayer中(交叉編譯鏈的結構其實蠻有意思,我在另一篇部落格中會好好分析)
DEST , 生成的ffmpeg共享庫libffmpeg.so儲存的路徑
SOURCE, ffmpeg原始碼的路徑
TOOLCHAIN ,用來儲存交叉編譯鏈的目錄路徑
SYSROOT , 用來儲存交叉編譯練進行連結步驟時查詢庫檔案的路徑
EXTRA_CFLAGS,用來幫助我們將264整合到ffmpeg時,查詢264標頭檔案的路徑
EXTRA_LDFLAGS,ffmpeg查詢264靜態庫的路徑
其他的變數估計都是見名知意的了,不明白的可以給我留言。
OK,編寫完指令碼後,先執行 config-ffmpeg-Android.sh 指令碼,對ffmpeg進行配置
PS. 如果執行配置指令碼時,遇到諸如 ” c compiler failed ....“ 之類的錯誤,多半是你配置指令碼中某個變數的路徑錯了。
配置指令碼執行完後,會打印出ffmpeg的配置資訊
從encoders 或者decoders中可以看出來,我們的ffmepg已經成功配置上了264
編譯完成後,會出現一個警告,這個可以忽略。
(3)配置指令碼config-ffmpeg-andorid.sh 執行完後,還需要修改ffmpeg目錄下的config.h檔案,同樣是修改 HAVE_LOGx的巨集值
----#define HAVE_LOG2 1
----#define HAVE_LOG2F 1
----#define HAVE_LOG10F 1
+++#define HAVE_LOG2 0
+++#define HAVE_LOG2F 0
+++#define HAVE_LOG10F 0
(4)修改完成後,執行編譯指令碼 ./make-ffmpeg-Android.sh 指令碼,指令碼內容如下:
#!/bin/bash
DEST=`pwd`/build/ffmpeg && rm -rf $DEST
SOURCE=`pwd`/ffmpeg
TOOLCHAIN=/tmp/vplayer
SYSROOT=$TOOLCHAIN/sysroot/
export PATH=$TOOLCHAIN/bin:$PATH
export CC="arm-linux-androideabi-gcc"
export LD=arm-linux-androideabi-ld
export AR=arm-linux-androideabi-ar
CFLAGS="-Os -fPIC -marm"
VERSION=armv7
cd $SOURCE
PREFIX="$DEST/$VERSION" && mkdir -p $PREFIX
EXTRA_LDFLAGS="-L../android-x264/lib"
make clean
make -j4 || exit 1
make install || exit 1
$CC -llog -lm -lz -shared --sysroot=$SYSROOT -Wl,--no-undefined -Wl,-z,noexecstack $EXTRA_LDFLAGS libavutil/*.o libavutil/arm/*.o libavcodec/*.o libavcodec/arm/*.o libavformat/*.o libswresample/*.o libswscale/*.o -o $PREFIX/libffmpeg.so -lx264 -L/home/yinjingyu/workspace/lab-project/ffmpegcpl/FFmpeg-Android/lib/-lx264
cp $PREFIX/libffmpeg.so $PREFIX/libffmpeg-debug.so
arm-linux-androideabi-strip --strip-unneeded $PREFIX/libffmpeg.so
echo "build successfully!"
注意,下載下來的ffmpeg原始碼需要修改一些原始檔才能順利編譯通過,不過這裡為了方便給大家貼出來錯誤資訊提供參考,我直接執行編譯指令碼,編譯過程出現錯誤
分析錯誤原因是型別衝突,具體我也沒深究,直接想了個簡單辦法:
首先要知道 strtod 是C庫函式,用來實現將字串轉化成double型別的資料。ffmpeg可能自己又重新實現了一套自己的函式叫做:avpriv_strtod,兩種實現導致了型別衝突。
我的解決方法就是註釋掉ffmpeg自己的實現,直接使用c庫的函式。具體步驟如下:
步驟1:進入我們交叉編譯鏈的目錄,如果你的配置指令碼和我一樣,那就應該是 /tmp/vplayer(之前我們專門拷貝了一份編譯鏈到該目錄下)。在該目錄下有一個sysroot目錄(用來儲存連結時用到的標頭檔案和庫),進入sysroot --> include 下,用vi 開啟 stdlib.h 檔案,新增如下內容:
+++//add by chance_yin 2013.12.27
+++#undef avpriv_strtod
+++#undef strtod
+++#define strtod strtod
步驟2:註釋掉 ffmpeg/compat/strtod.c中的所有程式碼
步驟3:在如下檔案: libavutil/eval.c、libavformat/rtmpproto.c 中的開頭位置新增如下程式碼,
#include
#undef avpriv_strtod
#undef strtod
#define strtod strtod
步驟4:上面的檔案修改完成後,再次執行編譯指令碼,又出現錯誤:
由於實驗室的專案用不到語音,所以對於錯誤:swri_audio_convert_init_arm,我的處理辦法是直接註釋掉,
剩下的關於 log2_tab.o multiple definition 的錯誤,就好解決了,
用vi 開啟: libavcodec/Makefile 、libavformat/Makefile 、libswresample/Makefile 檔案,將其中的
OBJS-$(CONFIG_SHARED) += log2_tab.o 註釋掉即可。
好了,原始碼的編譯算是告以段落了,貼出來編譯成功的圖,然後你就可以在FFmpeg-android/build/ffmpeg/armv7目錄下找到編譯完成的 libffmpeg.so 檔案了
結束:
之前實驗室專案一直用的是ffmpeg 0.x的版本,昨天把2.0版本的libffmpeg.so整合到專案中發現原來的程式碼在 avcodec_open2 報錯,在ffmpeg相應原始檔中打了log才發現是2.0之後,ffmpeg棄用了很多巨集。
專案老版本的程式執行到 avcodec_open2 出錯, 在原始碼此方法的實現中打log,
發現停在了“specific pixfmt not supported 。。。”,google一下,發現在ffmpeg2.0版本中,ffmpeg不再支援pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P;只要把該值設定成pCodecCtxEnc->pix_fmt = AV_PIX_FMT_YUV420P; 就可以了。
作者:chance_yin
相關推薦
Ubuntu下用NDK編譯移植FFmpeg 2.0(配置最新版x264)到Android平臺
將x264配置到ffmpeg中需要先編譯x264,生成靜態庫或動態庫。因為264的靜態庫本身不大(我編譯完成後是1.1M)且考慮到平臺移植問題,這裡選擇的是編譯生成靜態庫。 準備,新建工作空間 (1)建立總目錄FFmpeg-Android eg: mkdir workspace --> cd wor
在Mac 上 用NDK編譯libjpeg-turbo-2.0.0,使用cmake
libjpeg-turbo比libjpeg 現在版本升級到2.0.0,基於CMake編譯。依然還是一樣,按照官網介紹,libjpeg-turbo比libjpeg快2-6倍,得益於它高度優化的哈夫曼演算法。在許多情況下,libjpeg-turbo的效能可與專有的高速JPEG編解
ffmpeg2.6.2在Ubuntu下使用NDK編譯成.so檔案
參考blog:http://www.cnblogs.com/wainiwann/p/3785485.html 由於需要做視訊播放器,編解碼部分需要用到ffmpeg,沒辦法只能編譯ffmpeg.so 接下來就是參考網上多個ffmpeg的編譯過程,在多次嘗試後終於編譯成功,記
Ubuntu 下使用 Nginx 部署 .NET Core 2.0 網站
2.0 with gin .net lis spn 軟件 gpo cache 前言 本文介紹如何在 Ubuntu 16.04 服務器上部署 ASP.NET Core 2.0 Web 項目。 安裝 .NET Core 註冊 Microsoft 簽名密鑰: curl https
windows下用ndk r9編譯ffmpeg
網上大部分資料都是用ndk r4在linux下編譯ffmpeg,本文介紹在windows下用r9的ndk編譯ffmpeg2.2.4的歷程。 前面的配置借鑑了網上的資料,但還是詳細闡述下吧(ps:以下涉及到新建檔案的地方都必須是UNIX格式檔案): 2.用eclips
在ubuntu下用sublime text3編譯C++和pascal
amp cto windows ase wall ubuntu class dir sca 編譯C++: 選擇Tools -> Build System -> New Build System,把下面代碼拷貝進去,保存,自己起個名字。 然後打開C++文件,選擇T
Ubuntu 16.04下為Android編譯OpenCV 3.2.0 Manager
由於 ica 如何 setting -i add 標記 roi stripe http://johnhany.net/2016/07/build-opencv-manager-for-android-on-ubuntu/ 最近想在Android上嘗試一下SIFT和SU
hi3531下交叉編譯移植 FFMPEG X264 XVID
1. 主機環境: Thinkpad x230 CTO win7 64位 + VMware 11.1.2 + ubun
window環境下使用ndk編譯出android studio/Eclipse能使用的ffmpeg動態庫
window環境下使用ndk編譯出android studio 能使用的ffmpeg動態庫 目錄 ffmepg介紹 FFmpeg是一套可以用來記錄、轉換數字音訊、視訊,並能將其轉化為流的開源計算機程式。採用LGPL或GPL許可證。它提供了錄製、轉
FFMPEG與X264在windows下用VS編譯,VS與QT下執行與除錯
前言:最近在做視訊隱寫分析的畢業設,現在做的差不多了。打算髮幾篇文章整理一下最近的工作,為寫畢業論文做個準備。作為一隻寫第一次寫CSDN的渣渣,如果內容有誤敬請各位大佬指出。下面開始正篇先簡要介紹一下幾個概念H264格式視訊:是一種視訊流的格式,本身沒有音訊流。很多格式的視訊
vlc2.2.4在64位ubuntu下的交叉編譯
本文標題:vlc2.2.4在64位Ubuntu下編譯出32位的windows庫 注意好幾個關鍵的地方,折騰了好久 Ubuntu版本為16.04 64位的 一定要仔細看官方教程,看不仔細容易出錯哦 下面做幾點說明: 1. 前言 在32位的Ubuntu上嘗試了很久,失
Android 用NDK編譯FFmpeg(生成Android.mk可以放在原始碼框架內編譯)
mkdir jni && cd jni wget http://ffmpeg.org/releases/ffmpeg-0.6.tar.bz2 tar xf ffmpeg-0.6.tar.bz2 && mv ffmpeg-0.6 ffmpeg && cd
Ubuntu下用glade和GTK+開發C語言界面程序(一)
命令行 簡單的 暑假 all 位置 相同 write 3.0 面向對象的思想 前言:對於大學中計算機系的每年暑假的課設有太多想說的,能從中學到非常多東西,當然不排除打醬油的,這些能夠掠過哦,凡事都打醬油。人生也是打醬油的吧。2333。 對於大三曾經的課設一般的要求
ubuntu下用anaconda3安裝Tensorflow
con orf 自帶 ubun all nac 現在 sta -c 我裝的Anaconda3自帶的puython3.6,不過在Ubuntu下面是對3.5和3.6版本沒區別的(因為教程上是3.5,而我裝的是3.6) 裝完Anaconda3後 conda install --
Ubuntu下用命令行快速打開各類型文件(轉)
man hit hive linux內核 發現 manual uid 指定 常用命令 nautilus /media/pm/文檔/book/system/必讀nautilus /media/pm/文檔/book/android/ndk 內核/framerwork/andro
ubuntu下用expect實現密碼自動輸入
echo 遠程 shell ## 告訴 linux inux word linux下 每次筆記本一開機啟動,總會連用不著且礙事的觸摸板也一塊啟動。便想寫個腳本,讓電腦啟動時關閉觸摸板。(當然,我想更好的辦法是,修改系統啟動時的加載模塊,讓觸摸板不自動加載,但是目前還不知道用
Ubuntu下怎麽編譯並運行C、C++和Pascal語言?
tro 開始 用戶 步驟 ide gcc 但是 col inf 很多同學在安裝了Ubuntu的環境後,發現在Windows下的許多東西都打不開了,但是用網站上的在線IDE又不是很方便。 所以,ljn教你如何在Ubuntu下編譯並運行C、C++和Pascal。 一.編譯並
我在Ubuntu下用到的工具軟件(開發)
shadow 如果 comm git服務器 很多 平臺 nag 對比 scrip 上一篇主要是常用辦公軟件的介紹,這一篇則介紹我在軟件開發工作中用到的一些工具軟件。 使用電腦系統時,特別是在Windows下,軟件的費用實際上比硬件貴,尤其是某些專業軟件(這裏指的是正版軟件
基於Ubuntu 14.04 LTS編譯Android4.4.2原始碼
轉自:http://blog.csdn.net/gobitan/article/details/24367439 基於Ubuntu 14.04 LTS編譯Android4.4.2原始碼 Dennis Hu 2014-4-21 環境準備: 基
在Linux下用gcc編譯hello world
1. 確保Linux系統裡已經裝好了gcc 測試:輸入gcc後是如下的結果就說明已經安裝成功 2. 建立HelloWorld.c 使用 touch 建立一個空檔案; 用vim編輯 按下A或者I 插入 並輸入程式碼 輸入完成之後,按ESC退出 並輸入:wq(小寫)