ffmpeg和mplayer中求平均值得方法
1 ordinary c language level
#define avg2(a,b) ((a+b+1)>>1)
#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
顯而易見...,注意a,b宏表達式可能引出的副作用
2 SIMD by software
實現方法1:
inline static uint64_t BYTE_VEC(uint64_t x)
{
??? x |= x <<? 8;
??? x |= x << 16;
??? x |= x << 32;
??? return x;
}
static inline uint64_t avg2_no_rnd(uint64_t a, uint64_t b)
{
??? return (a & b) + (((a ^ b) & BYTE_VEC(0xfe))>> 1);
}
static inline uint64_t avg2(uint64_t a, uint64_t b)
{
??? return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >>1);
}
實現方法2:
#define op_avg_round(a,b)? a = ( ((a)|(b)) -((((a)^(b))&0xFEFEFEFEUL)>>1) )
#define op_avg_noround(a,b)? a = ( ((a)&(b)) + ((((a)^(b))&0xFEFEFEFEUL)>>1))
通 過軟件實現 singl instruction multi data,單指令多數據流,上述實現方法一樣方法1實現8個8bits寬度數據的同時平均,在64位cpu上使用方法2實現4個8bits寬度數據的同時 平均,在32位cpu上使用,簡單對此加以分析加法結果有2個成分,1個是進位,1個是邏輯和((a)&(b))<<1是進位 (((a)^(b))是邏輯和((a)&(b))<<1 +(((a)^(b))&0xFEFEFEFEUL) 為和,各自右移一位得到平均值,之所以是0xFE..,因為把每個字節的最后一個bit置零以免移位時進入下一個字節影響下一個字節的值((a)| (b)) 對應位在 0 1, 1 0, 1 1的3種情況下都得到1,所以((a)|(b))<<1表示進位+非滿進位,因為在0 1, 1 0這種情況下也產生了進位,剛好是它的邏輯和,其他分析同上
3 machine instruction levelAMD
3DNOW 指令:
#define AVG_3DNOW_OP(a,b,temp, size) /
"mov" #size " " #b ", " #temp "??/n/t"/
"pavgusb " #temp ", " #a"??????? /n/t"/
"mov" #size " " #a ", " #b"????? /n/t"
intel MMX指令:
#define AVG_MMX2_OP(a,b,temp, size) /
"mov" #size " " #b ", " #temp "??/n/t"/
"pavgb " #temp ", " #a"????????? /n/t"/
"mov" #size " " #a ", " #b "?????/n/t"
?
mplayer和ffmpeg的編譯大全
MPlayer下載
http://www.mplayerhq.hu/design7/dload.html
目前版本MPlayer v1.0rc2
MPlayer編譯
tar -xjvf MPlayer-1.0rc2.tar.bz2
cd MPlayer-1.0rc2
./configure
make
make install
如果出現以下錯誤
cabac.h: In function `get_cabac_noinline':
cabac.h:525: error: can't find a register in class `GENERAL_REGS' whilereloading `asm'
make[1]: *** [h264.o] 錯誤 1
在make前加入
export CFLAGS=-fomit-frame-pointer
make clean
?
ffmpeg的編譯大全
1. 首先獲取ffmpeg
很多人找不到怎么下載,其實之前ffmpeg可以通過cvs下載,不過最近他已經換成了更加強大的svn
如何使用SVN我這里不再介紹,網上還有大量的安裝和使用的文章可以借鑒,這里簡單羅列幾個SVN輔助的軟件:
SubVersion,從 http://subversion.tigris.org/ 下載,支持linux,我們這里就裝這個
TortoiseSVN,從 http://tortoisesvn.tigris.org/ 下載,是很不錯的SVN客戶端程序,為windows外殼程序集成到windows資源管理器和文件管理系統的Subversion客戶端,用起來很方便,commit動作變得就像Winrar右鍵壓縮一樣方便。
ok,那我們先裝subversion,記住最好之前裝過apr和apr-util,在apache.org網站能下到
wget http://subversion.tigris.org/downloads/subversion-1.3.2.tar.gz
tar zvxf subversion-1.3.2.tar.gz
cd subversion-1.3.2
./configure --with-apr=/usr/local/apr-httpd --with-apr-util=/usr/local/apr-util-httpd/
make
make install
到此,我們就可以通過svn命令獲取最新的ffmpeg了
svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
你會發現在你所在的目錄,自動出現一個ffmpeg的目錄,就是你下載的源代碼。
官網:http://ffmpeg.mplayerhq.hu/download.html
我們還不能這么快編譯ffmpeg,應該如果要讓ffmpeg支持更多格式的轉換,還需做一些前期工作
2. 支持mp3,linux當然是lame,下載解壓
http://sourceforge.net/projects/lame
?
? | lame-3.97.tar.gzMirror |
cd lame-3.97
./configure --enable-shared --prefix=/usr
./make
./make install
這里推薦盡量裝在/usr下,默認是裝在/usr/local下。這樣ffmpeg編譯都能順利的找到庫文件
3.支持Ogg Vorbis:
as4自帶相應的rpm包,你可以安裝一下如下rpm包
libvorbis, libvorbis-devel,libogg, libogg-devel
FC3和FC4應該是預設安裝了有關的library的,實際上要安裝的套件有4個:libvorbis、libvorbis-devel、libogg 和libogg-devel。您可以用以下指令檢查一下有沒有。
#rpm -qa | grep libogg
#rpm -qa | grep libvorbis
如果沒有的話,用yum安裝就可以了。
4.支持xvid x264,現在最流行的兩種高質量的壓縮格式
xvid的編譯安裝
Get the latest version on http://www.xvid.org/,and uncompress it on
your disk. Let's name the resulting source directory ${xvidcore}.
wget http://downloads.xvid.org/downloads/xvidcore-1.1.3.tar.gz
The next step allows you to configure the xvid sources.
# cd ${xvidcore}/build/generic
# ./configure
Some building options can be tuned thanks to the ./configure tool. You
can use your own CC and CFLAGS variables in order to override xvid's
default ones. To have a list of known options:
# ./configure --help
Now xvidcore is configured according to your specific platform. You
can still handwrite the platform.inc file in order to add/remove
specific flags that ./configure may have set them wrong.
It is time to build xvidcore:
# make
That creates a =build directory where all object files go, and where
the build targets are linked. If no error was reported by the build
process, then you can install it on your system:
# make install
This copies the shared and static libraries to the prefix location
passed to the ./configure tool (/usr/local by default). The xvid.h
include file is also copied during the "make install" run.
Voila, xvidcore is installed on your system, make sure your runtime
linker knows about the xvidcore prefix lib dir where it is
installed. And make also sure that it generates a symlink to its
SONAME. In case it would do not take care of the symlink itself:
# cd ${prefix}/lib
# ls libxvidcore.so.*
??? ls should list at least one libxvidcore.so.MAJOR.MINOR file
# ln -s libxvidcore.so.MAJOR.MINOR libxvidcore.so.MAJOR
You may also add a .so link to .so.MAJOR, so that applications linked
against .so are in fact linked to .so.MAJOR and thus ensures better
binary compatibility as we take care not changing the MAJOR number
until there is an incompatible ABI change.
# ln -s libxvidcore.so.MAJOR libxvidcore.so
#tar zvxf xvidcore-1.1.2.tar.gz
#cd xvidcore-1.1.2/build/generic/
#./configure --prefix=/usr
#make
#make install
H264/AVC 支援:x264
要壓HQ1080、iPod和PSP的影片,x264是少不了的。不過要安裝x264,就需要用yasm來編譯。那就先裝個yasm吧。
yasm下載網址:http://www.tortall.net/projects/yasm/releases/yasm-0.6.0.tar.gz
最新的 下載:???? Source.tar.gz 0.6.2
#tar xzvf yasm-0.6.0.tar.gz
#cd yasm-0.6.0
#./configure --prefix=/usr/local/yasm
#make
#make install
#export PATH="$PATH:/usr/local/yasm/bin"
#vi /etc/profile
--[在最後,插入]--
export PATH="$PATH:/usr/local/yasm/bin"
--[存檔並關閉]--
跟ffmpeg一樣,x264的官網也是鼓勵大家 checkout SVN來取得最新版本。但據SupeSite在2007年5月16日的說明指出官網的x264最新版有Bug,無法正常在一些Intel的CPU上編譯安 裝(甚麼雙至強、四至強CPU嘛,是指雙核和四核嗎?)。不過起碼米奇在公司的P4 2.8GHz CPU安裝沒有問題啦,所以...管它。如果您遇上問題的話,就去下載SupeSite的開發公司Comsenz的版本吧,不過先旨聲明,那個改版的授權 還是不是原來的GPL就不知道了。如果您在意於授權的話,那就用SVN checkout吧,我想那問題可能在您安裝時已經修正好了。
x264的獲取同樣是采用svn方式,看來svn取代cvs不遠了
svn co svn://svn.videolan.org/x264/trunk x264
cd x264
./configure --prefix=/usr --enable-shared
make
make install
5.AC3和dts編碼的支持
as4系統似乎已經支持ac3編碼,編譯的時候只要加--enable-a52--enable-gpl參數就行
現在的ffmpeg又沒附有liba52了,所以,還是自己動手裝吧...
下載網站:http://liba52.sourceforge.net/
# tar zxvf a52dec-0.7.4.tar.gz
# cd a52dec-0.7.4
# ./configure --enable-shared --prefix=/usr
# make
# make install
6.mpg4 aac格式支持,由于服務器還針對手機用戶服務,所以,類似aac,mpg4鈴聲格式的支持,我們也得做。這里我們安裝faad2和faac就行
faac是用來壓製AAC音軌的,而faad2就是AAC音軌的解碼器。手機鈴聲和MP4影片都是使用AAC作聲音編碼的,所以要裝這個。
另外,faac和faad2都可以配合libmp4v2來安裝,有些網站說需要先安 裝libmp4v2,(http://mpeg4ip.net/) 不過米奇就發覺只要編譯faac和faad2時加入適當參數,就可以連同libmp4v2一同安裝了。
下載請到http://www.audiocoding.com/downloads.html
FAAD2的編譯
cd faad2
autoreconf -vif
./configure --prefix=/usr --with-mp4v2 --enable-shared
make
make install
faac的編譯
cd faac
chmod +x bootstrap
./bootstrap
./configure --prefix=/usr --with-mp4v2 --enable-shared
make
make install
Comsenz版下載網址:http://download.discuz.net/env/video/faac-1.25-Comsenz.tar.bz2
#tar xjvf faac-1.25-Comsenz.tar.bz2
#cd faac-Comsenz
#autoreconf -vif
#./configure --prefix=/usr --with-mp4v2 --enable-shared
#make
#make install
要知道安裝了faac和faad2之後有沒有安裝好libmp4v的話,只要找一找/usr/lib目錄裡有沒有 libmp4v2.so等一系列檔案就可以了。找不到的話,就到這裡去下載,安裝好之後再重頭安裝faac和 faad2了。
7.支持3gp格式,這也是現在好多手機支持的格式,因為手機用戶是我們的主要用戶,所以也得支持編譯
編譯的時候加上--enable-amr_nb --enable-amr_wb參數就行,根據編譯系統的提示,所以我們得下載一
些編譯3gp所需得文件。
wget http://www.3gpp.org/ftp/Specs/ar ... 6.204/26204-510.zip
解壓以后把里面的文件都拷貝到libavcodec/amrwb_float
wget http://www.3gpp.org/ftp/Specs/ar ... 6.104/26104-510.zip
解壓以后把里面的文件都拷貝到libavcodec/amr_float
3GPP AMR Floating point 和AMR-Wideband支援:libamrnb、libamrwb
3GP 影片的影像是h263編碼,而聲音就用AMR-NB或AMR-WB編碼,所以要轉換手機影片,就要安裝AMR程式庫。最初坊間的安裝方式都是到3GPP官 網去下載那些連名字也搞不懂的檔案來,放在ffmpeg裡的指定目錄去跟ffmpeg一同編譯的,但現在已經有人抽取了出來而成為獨立的程式庫,安裝起來 就簡單得多了。
下載網址:http://www.penguin.cz/~utx/amr
libamrnb
#tar xjvf amrnb-7.0.0.0.tar.tar
#cd amrnb-7.0.0.0
#./configure --prefix=/usr --enable-shared
#make
#make install
libamrwb
#tar xjvf amrwb-7.0.0.2.tar.tar
#cd amrwb-7.0.0.2
#./configure --prefix=/usr --enable-shared
#make
#make install
8. DTS 支援:libdca
ffmpeg已經內含了用來解碼DTS的libdca,所以不用安裝,也沒有要入加的參數。
9. 安裝ffmpeg
安裝完成必要的程式庫之後,終於可以動手安裝ffmpeg本體了。如果您先前曾經安裝過ffmpeg的話,就先把ffmpeg的源碼目錄刪掉,再次 checkout個新版本回來安裝吧。
#svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk/usr/local/src/ffmpeg
#cd /usr/local/src/ffmpeg
#./configure --prefix=/usr --enable-gpl --enable-shared --enable-libmp3lame--enable-libvorbis --enable-libamr-nb --enable-libamr-wb --enable-libxvid --enable-libx264 --enable-liba52--enable-liba52bin --enable-libfaac --enable-libfaad --enable-libfaadbin--enable-pp --enable-pthreads --disable-ffserver --disable-ffplay
#make clean && make
#make install
經過可以去看一節動畫的時間編譯之後,你應該可以在/usr/bin目錄裡找到ffmpeg程式。輸入ffmpeg便會列出用了甚麼參數來編譯這個 ffmpeg和它的版本。米奇試過用以這程序來安裝的ffmpeg來編製和解壓3GP、Xvid、mov、wmv9、msmpeg4、MPEG2+AC3 音源、h264+aac音源的mkv、PSP用的MP4和FLV影片,都沒有問題,只有wmv7的影片無法解碼,相信已經對應得到大部份現時流行的影音格式了。
可以用 ffmpeg -threads [thread_count] -deinterlace -i [input_file] -ac 2-ab [audio_bitrate] -acodec libfaac -vcodec libx264 -b [video_bitrate][output_file] 來產生 H.264+AAC 的mp4 檔案了。
ffmpeg編譯及使用
ffmpeg編譯及使用
1 ffmpeg介紹
ffmpeg是音視頻的分離,轉換,編碼解碼及流媒體的完全解決方案,其中最重要的就是libavcodec庫。它被mplayer或者xine使用作為解碼器。還有,國內比較流行的播放器影音風暴或MyMPC的后端ffdshow也是使用ffmpeg的解碼庫的。
ffmpeg軟件包經編譯過后將生成三個可執行文件,ffmpeg,ffserver,ffplay。其中ffmpeg用于對媒體文件進行處理,ffserver是一個http的流媒體服務器,ffplay是一個基于SDL的簡單播放器。
ffmpeg 中有五個庫文件,libavcodec,libavformat,libavutil,libswscale,libpostproc,其中庫 libavcodec,libavformat用于對媒體文件進行處理,如格式的轉換;libavutil是一個通用的小型函數庫,該庫中實現了CRC校 驗碼的產生,128位整數數學,最大公約數,整數開方,整數取對數,內存分配,大端小端格式的轉換等功能;libswscale,libpostproc 暫時不知道何用。
2 ffmpeg下載
最新的ffmpeg可以通過svn下載,SVN輔助的軟件有:
SubVersion,從 http://subversion.tigris.org/下載,支持linux。
TortoiseSVN,從 http://tortoisesvn.tigris.org/下載,是很不錯的SVN客戶端程序,為windows外殼程序集成到windows資源管理器和文件管理系統的Subversion客戶端,用起來很方便。
subversion安裝,記住最好之前裝過apr和apr-util,在apache.org網站能下到
wget http://subversion.tigris.org/downloads/subversion-1.3.2.tar.gz
tar zvxf subversion-1.3.2.tar.gz
cd subversion-1.3.2
./configure --with-apr=/usr/local/apr-httpd--with-apr-util=/usr/local/apr-util-httpd/
make
make install
如果安裝了FC6,它已經帶了svn,不用裝了。
ffmpeg的下載:我們就可以通過svn命令獲取最新的ffmpeg,命令如下:
svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
3 ffmpeg支持庫的安裝
* xvid
xvid的獲取地址如下:
http://www.xvid.org/
wget http://downloads.xvid.org/downloads/xvidcore-1.1.3.tar.gz
配置編譯
? ?for x86
#./configure --prefix=/usr/local
#make
#make install
? ?for arm
#CC=arm-linux-gcc ./configure--prefix=/usr/local/arm/arm-linux --build=i686-pc-linux --host=arm-linux--target=arm-linux
#make
#make install
* x264
x264的獲取地址如下:
svn co svn://svn.videolan.org/x264/trunk x264
配置編譯
? ?for x86
#./configure --enable-shared --prefix=/usr/local
#make
#make install
? ?for arm
#CC=arm-linux-gcc ./configure --enable-pthread--enable-shared --host=arm-linux
--prefix=/usr/local/arm/arm-linux
#make
#make install
* 支持mp3
lame的獲取地址如下: http://lame.sourceforge.net/index.php
配置編譯
? ?for x86
./configure --enable-shared --prefix=/usr/local
* 支持Ogg Vorbis:
* AC3和dts編碼的支持
libdts編譯參數
./configure --prefix=/usr
make
make install
* mpg4 aac格式支持,如果ffserver服務器還針對手機用戶服務,所以,類似aac,mpg4鈴聲格式的支持,我們也得做。這里我們安裝faad2和faac就行,下載請到http://www.audiocoding.com/modules/mydownloads/,http://prdownloads.sourceforge.net/faac
? ?FAAD2的編譯
cd faad2
autoreconf -vif
./configure --prefix=/usr --with-mp4v2 --enable-shared
make
make install
? ?faac的編譯
cd faac
chmod +x bootstrap
./bootstrap
./configure --prefix=/usr --with-mp4v2 --enable-shared
make
make install
在編譯ffmpeg,在configure時加上--enable-amr_nb --enable-faad --enable-faac參數。
* 支持3gp格式,這也是現在好多手機支持的格式,所以也得支持編譯
編譯的時候加上--enable-amr_nb --enable-amr_wb參數就行,根據編譯系統的提示,所以我們得下載一些編譯3gp所需得文件。
源碼網址:http://www.3gpp.org/ftp/Specs
wget http://www.3gpp.org/ftp/Specs/ar ... 6.204/26204-510.zip
解壓以后把里面的文件都拷貝到libavcodec/amrwb_float
wget http://www.3gpp.org/ftp/Specs/ar ... 6.104/26104-510.zip
解壓以后把里面的文件都拷貝到libavcodec/amr_float
* ffmpeg支持VC1格式
? ? 微軟ASF格式的三個版本,WMV1,WMV2,WMV3分別對應MediaPlayer的版本7,8和9,所以很多時候會稱VC1為WMV3或 WMV9,都是它了,有時候在代碼里,也能看到稱呼它為VC9的。因為微軟還沒有正式公開這種格式,所以當前對VC1的支持還很不完善。本文基本是根據Multimedia Mike的一篇博客翻譯和完善而來。
? ? (1) 首先要下載 SMPTE VC-1 reference decoder,這個組織是要收費的,可以從這里下載免費的。
? ? (2) 在ffmpeg目錄下的libavcodec目錄下面,建立目錄libvc1。
? ? (3) 將VC1_reference_decoder_release6/decoder/目錄中的*.c和*.h文件全部copy到libvc1目錄下。
? ? (4) 將VC1_reference_decoder_release6/shared/目錄中的*.c和*.h文件全部copy到libvc1目錄下。
? ? (5) 將 libvc1-makefile.txt放到libvc1下的Makefile文件。
? ? (6) 將smpte-vc1.c文件放到libavcodec目錄下。
? ? (7) 修改libavcodec目錄下的vc9.c,將文件最后的wmv3_decoder這個AVCodec的structure,用#if 0和#endif包含起來,也就是使它失效了。
? ? (8) 修改libavcodec目錄下的allcodecs.c,將register_avcodec(&wmv3_decoder)上下的注釋去掉,使它發揮作用。
? ? (9) 修改libavcodec目錄下的Makefile,把OBJS的列表中加入smpte-vc1.o。
? ? (10)修改ffmpeg主目錄下的Makefile文件,把-L./libavcodec/libvc1 -lvc1$(BUILDSUF)加入到FFLIBS后面。
? ? (11) 進入ffmpeg/libavcodec/libav1,執行make
? ? (12) 到ffmpeg主目錄下,執行config;make;make install。config時根據實際情況帶參數。
* 采用ffmpeg轉碼制作FLV文件的方法
? ? 采用ffmpeg轉碼制作FLV文件,和轉碼成其它媒體類型的重要差別是一定要有lame庫支持,因為FLV的聲音編碼采用mp3格式,非lame這個東東不行。編譯ffmpeg中加入lame庫真是一場災難,特別在windows下,很多參數都不能發揮作用,最后直接手工copy和改一些文件,記錄如下:
? ? (1) 如果在Windows下編譯,第一步當然是下載MinGW和MSYS來裝上了。到http://mingw.sourceforge.net/去下載最新版的MinGW-5.0.2.exe和MSYS-1.0.11-2004.04.30-1.exe。
? ? (2) 先安裝MinGW,直接運行MinGW-5.0.2.exe安裝,選擇目錄,譬如選擇D:\MinGW為安裝目錄。安裝時需要選擇gcc和make模塊,安裝文件本身很小,會從網上下載模塊來安裝。
? ? (3) 然后安裝MSYS,也是直接運行MSYS-1.0.11-2004.04.30-1.exe安裝。安裝目錄一般選擇D:\MinGW\bin \1.0。,安裝過程會詢問剛才安裝MinGW的目錄,輸入D:\MinGW,其它都回答'Y'就搞定了。如果不清楚,可以看這個圖片效果。
? ? (4) 運行MSYS,桌面上有個圖標,雙擊就運行了,運行結果是一個模擬unix的命令窗口,后面的編譯都在這種狀態下進行。前面4步在linux不需要。
? ? (5) 到http://lame.sourceforge.net/去下載最新版的lame-3.97b2.tar.gz,copy到你認為合適的地方,解壓后進入lame解壓出來的目錄中。執行
? ?? ???./configure--prefix=PREFIX
? ?? ???make
? ?? ???make install
? ? (6) 就把編譯出來的include下的lame目錄copy到/usr/include目錄下,把lib下的幾個庫文件都copy到/usr/lib目錄 下。這里注意有個變化,如果只copy lib目錄下的靜態庫到/usr/lib下,就是只copy libmp3lame.a文件,編譯出來的ffmpeg最終就不會對libmp3lame的動態庫有依賴關系,這是因為編譯首先找動態庫,動態庫沒有才找靜態庫。如果不做這個copy,后面編譯ffmpeg時無論如何指定參數,都會報錯LAME not found,不知道是哪里的bug。
? ? (7) 從http://ffmpeg.mplayerhq.hu/取得最新的ffmpeg,現在自由軟件都大量采用SVN了,要先裝一個SVN,可以去http://tortoisesvn.tigris.org/下載windows版的SVN,去http://subversion.tigris.org/下載linux版的SVN。SVN如何編譯安裝這里就省略了。
? ? (8) 如果在windows下,打開解壓后的ffmpeg目錄下的Makefile文件,在FFLIBS的那一行后面加上-lmp3lame$(BUILDSUF)。這個也不知道是哪個bug引起的,搞了好長時間才搞出來,郁悶。Linux下不用這樣。
4 ffmpeg的編譯
配置編譯
for x86
#./configure --prefix=/usr --enable-gpl --enable-shared--enable-mp3lame --enable-amr_nb --enable-amr_wb --enable-amr_if2--enable-libogg --enable-vorbis --enable-xvid --enable-a52 --enable-a52bin--enable-faadbin --enable-dts --enable-pp --enable-faad --enable-faac--enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay
make
make install
補充1:
關于3gp的編譯,如果大家要編譯--enable-amr_nb-fixed,那就不能跟--enable-amr_nb同時編譯,我不大清楚這兩者到底有什么區別,似乎
fixed是修正版,管他呢,編譯的方法:
wget http://www.3gpp.org/ftp/Specs/ar ... 6.073/26073-510.zip
解壓以后把里面的文件都拷貝到libavcodec/amr目錄下
修改libavcodec/amr/makefile 找到CFLAGS =-Wall -pedantic-errors -I. $(CFLAGS_$(MODE)) -D$(VAD) 換成CFLAGS = -Wall -I.
$(CFLAGS_$(MODE)) -D$(VAD) -DMMS_IO
整體編譯參數就是
#./configure --prefix=/usr --enable-gpl --enable-shared--enable-mp3lame --enable-amr_nb-fixed --enable-amr_wb --enable-amr_if2--enable-libogg --enable-vorbis --enable-xvid --enable-a52 --enable-a52bin--enable-dts --enable-pp --enable-faad --enable-faadbin --enable-faac--enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay
make
make install
for x86的簡易配置
#./configure --prefix=./install --disable-shared--enable-pthreads --enable-libx264 --enable-libxvid --arch=i686 --enable-gpl
#make
#make install
for arm
配置編譯
#./configure--prefix=/home/zht/redhatzht/sources/image-colletct/ffmpeg/install--enable-static --disable-shared --enable-libx264 --enable-libxvid--cross-compile --cc=arm-linux-gcc --arch=arm --enable-gpl --disable-strip--disable-network --disable-ipv6 --disable-vhook --disable-audio-beos--disable-audio-oss --disable-mpegaudio-hp??--enable-pthreads--enable-small --disable-parsers --disable-debug
#make
#make install
注意:
(1)“/home/zht/redhatzht/sources/image-colletct/ffmpeg”為ffmpeg源碼所在目錄。
(2)“/usr/local/arm”為arm-linux-gcc交叉編譯器所在目錄。
(3) 如果庫文件安裝在/usr/local/lib目錄中導致配置失敗,可以在/etc/ld.so.conf文件中添加/usr/local/lib目錄,然后執行#ldconfig。
? ? x86上的ldconfig不能在arm上運行,arm上的ldconfig工具是在建立交叉編譯器時,編譯glibc是產生的,可以拷貝到arm-linux中。
(4) 本文大部分內容來自網絡,其中xvid,x264的庫,我親手安裝過,ffmpeg的配置編譯for x86的簡易配置,for arm,我親手配置編譯過,并在x86,arm上可用,編譯配置都是采用靜態庫。
5 ffmpeg用法
ffmpeg作為媒體文件處理軟件,基本用法如下:
ffmpeg -i INPUTfile [OPTIONS] OUTPUTfile
輸入輸出文件通常就是待處理的多媒體文件了。可以是純粹的音頻文件,純粹的視頻文件,或者混合的。ffmpeg支持絕大部分的常見音頻,視頻格式,象常見的 各種mpeg,AVI封裝的DIVX和Xvid等等,具體的格式支持列表可以使用ffmpeg -formats查看或直接查閱文檔。
另外,由于Linux把設備視為文件,因此-i選項后可以跟設備名。比如DV,視頻卡,光驅或者其它的各類設備。輸出的內容通過
Options調整,其主要的選項如下:
-vcodec??視頻流編碼方式
-b? ?? ???視頻流碼率(默認只有200k,一般都需要手動設置,具體的數值視codec選擇而定)
-r? ?? ???視頻流幀數(一般說來PAL制式通常用25,NTSC制式通常用29)
-s? ?? ?? ?視頻解析度(分辨率,也要視codec和你的需要而定。另:具體寫法使用“數字x數字”的形式)
-t? ?? ?? ?處理持續時間。
-acodec? ?音頻流編碼方式
-ab? ?? ?? ? 音頻流碼率(默認是同源文件碼率,也需要視codec而定)
-ar? ?? ?? ???音頻流采樣率(大多數情況下使用44100和48000,分別對應PAL制式和NTSC制式,根據需要選擇)
-vn??屏蔽視頻流
-an??屏蔽音頻流
-author??設置媒體文件的作者
-title??設置媒體文件的題目
-f??強制使用某種格式
-target type 使用預置的格式轉換(可以轉成dvd,vcd或svcd)
除此之外還有些更高級的選項,如設定vbr,或設定high quality,或者設定vbr的buff和max/min碼率,象一般我們自用的dvd抓軌啦,DV轉vcd dvd啦,網上下載的電影轉成vcd或dvd都不一定需要用到它們。
常用命令選項說明
-fromats 顯示可用的格式
-f fmt 強迫采用格式fmt
-I filename 輸入文件
-y 覆蓋輸出文件
-t duration 設置紀錄時間hh:mm:ss[.xxx]格式的記錄時間也支持(截圖需要)
-ss position 搜索到指定的時間[-]hh:mm:ss[.xxx]的格式也支持
-title string 設置標題
-author string 設置作者
-copyright string 設置版權
-comment string 設置評論
-target type 設置目標文件類型(vcd,svcd,dvd),所有的格式選項(比特率,編解碼以及緩沖區大小)自動設置,只需要輸入如下的就可以了:ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
-hq 激活高質量設置
-b bitrate 設置比特率,缺省200kb/s
-r fps 設置幀頻,缺省25
-s size 設置幀大小,格式為WXH,缺省160X128.下面的簡寫也可以直接使用:Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576
-aspect aspect 設置橫縱比 4:316:9 或 1.3333 1.7777
-croptop/botton/left/right size 設置頂部切除帶大小,像素單位
-padtop/botton/left/right size 設置頂部補齊的大小,像素單位
-padcolor color 設置補齊條顏色(hex,6個16進制的數,紅:綠:藍排列,比如 000000代表黑色)
-vn 不做視頻記錄
-bt tolerance 設置視頻碼率容忍度kbit/s
-maxrate bitrate設置最大視頻碼率容忍度
-minrate bitreate 設置最小視頻碼率容忍度
-bufsize size 設置碼率控制緩沖區大小
-vcodec codec 強制使用codec編解碼方式. 如果用copy表示原始編解碼數據必須被拷貝.(很重要)
-ab bitrate 設置音頻碼率
-ar freq 設置音頻采樣率
-ac channels 設置通道,缺省為1
-an 不使能音頻紀錄
-acodec codec 使用codec編解碼
-vd device 設置視頻捕獲設備,比如/dev/video0
-vc channel 設置視頻捕獲通道DV1394專用
-tvstd standard 設置電視標準 NTSC PAL(SECAM)
-dv1394 設置DV1394捕獲
-av device 設置音頻設備 比如/dev/dsp
-map file:stream 設置輸入流映射
-debug 打印特定調試信息
-benchmark 為基準測試加入時間
-hex 傾倒每一個輸入包
-bitexact 僅使用位精確算法 用于編解碼測試
-ps size 設置包大小,以bits為單位
-re 以本地幀頻讀數據,主要用于模擬捕獲設備
-loop 循環輸入流。只工作于圖像流,用于ffserver測試
5 example
(1) ffmpeg的使用
"Video and Audio grabbing"
FFmpeg can use a video4linux compatible video sourceand any Open Sound System audio source:? ?? ?? ?
? ?? ???ffmpeg/tmp/out.mpg
Note that you must activate the right video source andchannel before launching ffmpeg. You can use any TV viewer such as
xawtv (<http://bytesex.org/xawtv/>) by Gerd Knorr which I findvery good. You must also set correctly the audio recording
levels with a standard mixer.
"Video and Audio file format conversion"
* You can input from YUV files:? ???
? ?? ???ffmpeg -i /tmp/test%d.Y/tmp/out.mpg
The Y files usetwice the resolution of the U and V files. They are raw files, without header.They can be generated by all decent video decoders. You must specify the sizeof the image with the -s option if ffmpeg cannot guess it.
* You can input from a RAW YUV420P file:??? ?? ?
? ?? ???ffmpeg -i/tmp/test.yuv /tmp/out.avi
The RAW YUV420P is a file containing RAW YUV planar,for each frame first come the Y plane followed by U and V planes, which arehalf vertical and horizontal resolution.
* You can output to a RAW YUV420P file:??? ?? ?
? ?? ???ffmpeg -imydivx.avi -o hugefile.yuv
* You can set several input files and outputfiles:? ?? ?? ?
? ?? ???ffmpeg -i/tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
Convert the audio file a.wav and the raw yuv video filea.yuv to mpeg file a.mpg
* You can also do audio and video conversions at thesame time:? ?? ?? ?
? ?? ???ffmpeg -i/tmp/a.wav -ar 22050 /tmp/a.mp2
Convert the sample rate of a.wav to 22050 Hz and encodeit to MPEG audio.
* You can encode to several formats at the same timeand define a mapping from input stream to output streams:? ???? ?
? ?? ???ffmpeg -i/tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0
Convert a.wav to a.mp2 at 64 kbits and b.mp2 at 128kbits. "-map file:index" specify which input stream is used for eachoutput stream, in the order of the definition of output streams.
* You can transcode decrypted VOBs? ???? ?
? ?? ???ffmpeg -isnatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128snatch.avi
This is a typical DVD ripper example, input from a VOBfile, output to an AVI file with MPEG-4 video and MP3 audio, note that in this command we use B frames so theMPEG-4 stream is DivX5 compatible, GOP size is 300 that means an INTRA frameevery 10
seconds for 29.97 fps input video.??Also theaudio stream is MP3 encoded so you need LAME support which is enabled using--enable-mp3lame when configuring.??The mapping is particularlyuseful for DVD transcoding to get the desired audio language.
NOTE: to see the supported input formats, use ffmpeg-formats.
(2) ffplay的使用
ffplay - FFplay media player
SYNOPSIS
ffplay [options] input_file
DESCRIPTION
FFplay is a very simple and portable media player usingthe FFmpeg libraries and the SDL library. It is mostly used as a test bench forthe various APIs of FFmpeg.
OPTIONS
"Main options"
show help force displayed width force displayed heightdisable audio disable video disable graphical display force format
"Advanced options"
show the stream duration, the codec parameters, thecurrent position in the stream, and the audio/video synchronisation drift.force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful if youare doing stream with the RTSP protocol.
set the master clock to audio ( type=audio), video (type=video) or external ( type=ext). Default is audio. The master clock is usedto control audio-video synchronization. Most media players use audio as masterclock, but in some cases (streaming or high quality broadcast) it is necessaryto change that. This option is mainly used for debugging purposes.
(3) ffserver的使用
ffsserver - FFserver video server
SYNOPSIS
ffserver [options]
DESCRIPTION
FFserver is a streaming server for both audio andvideo. It supports several live feeds, streaming from files and time shiftingon live feeds (you can seek to positions in the past on each live feed,provided you specify a big enough feed
storage in ffserver.conf).
This documentation covers only the streaming aspects offfserver / ffmpeg. All questions about parameters for ffmpeg, codec questions,etc. are not covered here. Read ffmpeg-doc.html for more information.
OPTIONS
print the license print the help use configfile insteadof /etc/ffserver.conf
6 其他(參考)
(1)mencoder篇
? ?首先獲取mplayer軟件包極其mplayer官網上自帶的codecs.如果喜歡mplayer,也可以下載gui和font.關于mplayer-1.0rc1在71.21的/home/zhengyu/tools中能找到.如果需要網上下載,可以去官網:http://www.mplayerhq.hu/de...下載rc1地址如
下:http://www1.mplayerhq.hu/M...最新的svn版本:http://www1.mplayerhq.hu/M...官網同時也給出了一些codec,其中就有rm格式的codec:http://www1.mplayerhq.hu/M...?? xplore也提供下載,mplayer1.0rc1下載,codec下載.
? ?下載完成之后,將tar vxjf essential-20061022.tar.bz2;sudo mkdir -p/usr/lib/codecs;sudo cp -rf essential-20061022/*
/usr/lib/codecs;然后解包mplayer,按如下方式編譯:
./configure --prefix=/usr/local --enable-gui--enable-largefiles??--enable-gif --enable-png --enable-jpeg--language=zh_CN --with-codecsdir=/usr/lib/codecs/
make
(sudo make install)
? ?然后就可以使用mencoder,當然也有一個沒有gui的mplayer可以播放各種視頻了.不過我們需要的是mencoder.至此,ffmpeg+mencoder搭建完成.
(2) 常見操作說明
對于ffmpeg,可以將除swf,rmvb,wmav9以外的視頻/音頻格式轉換成flv/mp3,同時可以截取這些視頻文件中的某個時間的該幀圖片.這些實際上就是一個視頻播客顯示的部分.對于mencoder,支持各種常見格式的視頻/音頻轉換成flv/mp3.或者轉換成avi.
1) ffmpeg進行操作的常用方法:
? ?* 轉換成flv文件:ffmpeg -i infile.* -y (-ss second_offset -ar ar -ab ab -r vr -b vb-s vsize) outfile.flv
? ?? ???其中second_offset是從開始的多好秒鐘.可以支持**:**:**格式,至于ar,ab是音頻的參數,可以指定ar= 22050,24000,44100(PAL制式),48000(NTSC制式),后兩種常見,ab=56(視音頻協議的codec而定,如果要聽高品質,則80以上).vr,vb,vsize是視頻參數,可以指定vr=15,25(PAL),29(NTSC),vb=200,500,800,1500 (視視頻協議的codec而定,可以通過查看專業的codec說明文檔獲取,如果你手頭有一份詳細的各種codec的文檔,請提供一份給我,不勝感 激.),還有一些參數-acodec ac -vcodec vc(ac指定音頻codec,ar和ab可以省去,vc指定視頻codec,vr和vb可以省去,自動采用相應的codec參數)還有很多高級參數,如 -qmin,-qcale等,請查看詳細文檔。還有-an和-vn參數,分別從多媒體文件中提取出純粹視頻和音頻。另,如果你是用shell批量處理,請使用-y參數覆蓋生成flv.
? ?* 截取圖片:ffmpeg-i infile.* -y (-ss second_offset) -t 0.001 -s msize (-f image_fmt) outfile.jpg
? ?? ?? ?? ?其中second_offset同上,msize同vsize,圖片大小.image_fmt=image2強制使用 jpg,image_fmt=gif,強制使用gif格式.還可以用-vframes fn指定截取某幀圖片,fn=1,2,3,...
2)mencoder操作
? ? mencoder的作用主要在視頻轉碼方面.在安裝完mplayer后,mencoder也編譯生成了.可以man mencoder獲取mencoder的說明文檔. mencoder的參數更加復雜,不過也無非是音頻處理視頻處理兩個方面,可以參看網絡例子:http://www.masoncn.com/pos...這里不作詳細的列舉了.
? ?mencoder進行操作的常用方法: mencoder infile.* -o outfile.* [-ovc 目標視頻格式] [-oac 目標音頻格式] [-of 目標文件格式]
? ?* 轉換成flv文件: mencoder infile.* -o outfile.flv -of lavf -oac mp3lame -lameoptsabr:br=56 -ovc lavc -lavcopts
vcodec=flv:vbitrate=150:mbd=2:mv0:trell:v4mv:cbp:last_pred=3-srate 22050
? ?* 轉換成avi文件: mencoder infile.* -o outfile.avi -of avi -oac mp3lame -lameoptspreset=64 -ovc xvid -xvidencopts
bitrate=600
? ?* 轉換成wmv文件(復雜寫法,其中高級參數可以省去): mencoder infile.* -o outfile.wmv -of lavf -ofps 25 -oac mp3lame-lameopts
cbr:preset=128 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=768:mbd=2:mv0:trell:v4mv:cbp:last_pred=3-vf scale=320:240 -srate
22050 -sws 9 -subcp cp936 -subpos 0 -subalign 0-subfont-text-scale 3 -lavfopts i_certify_that_my_video_strea
? ?其中-ovc,-oac和-of是必須的,-ovc是指定視頻codec,指定了ovc之后通常帶一個該codec的opt參數,-oac是指定音頻 codec,也會在其后帶一個codec的opt參數.可以指定細節以決定視頻音頻質量和轉換速率.具體的細節可以參看專業的技術文檔.
7??ffmpeg配置選項
[root@web ffmpeg]# ./configure --help
Usage: configure [options]
Options: [defaults in brackets after descriptions]
Standard options:? ?基本選項參數
??--help? ?? ???? ?? ?? ? 顯示此幫助信息|print this message
??--log[=FILE|yes|no]? ???記錄測試并輸出到config.err文件|log tests and output to FILE [config.err]
??--prefix=PREFIX? ???? ? 安裝程序到指定目錄(默認/usr/local)|install in PREFIX [/usr/local]
??--libdir=DIR? ???? ?? ? 安裝庫到指定目錄(默認prefix/lib)|install libs in DIR [PREFIX/lib]
??--shlibdir=DIR? ???? ???指定共享庫路徑(默認prefix/lib)|install shared libs in DIR [PREFIX/lib]
??--incdir=DIR? ???? ?? ? 指定includes路徑(默認prefix/include/ffmpeg)|installincludes in DIR[PREFIX/include/ffmpeg]
??--mandir=DIR? ???? ?? ? 指定man page路徑(默認prefix/man)install manpage in DIR [PREFIX/man]
??--enable-mp3lame? ???? ?啟用mp3編碼libmp3lame(默認關閉)enableMP3 encoding via libmp3lame[default=no]
??--enable-libogg? ???? ? 啟用ogg支持libogg(默認關閉)enable Oggsupport via libogg [default=no]
??--enable-vorbis? ???? ? 啟用Vorbis支持libvorbis(默認關閉)enableVorbis support via libvorbis [default=no]
??--enable-faad? ???? ?? ?啟用faad支持libfaad(默認關閉)enable FAADsupport via libfaad [default=no]
??--enable-faadbin? ???? ?啟用faad運行時鏈接支持(默認關閉)build FAAD support with runtime linking[default=no]
??--enable-faac? ???? ?? ?啟用faac支持libfaac(默認關閉)enable FAACsupport via libfaac [default=no]
??--enable-libgsm? ???? ? 啟用GSM支持libgsm(默認關閉)enable GSMsupport via libgsm [default=no]
??--enable-xvid? ???? ?? ?啟用xvid支持xvidcore(默認關閉)enableXviD support via xvidcore [default=no]
??--enable-x264? ???? ?? ?啟用H.264編碼(默認關閉)enable H.264 encoding via x264 [default=no]
??--enable-mingw32? ???? ?啟用MinGW本地/交叉win環境編譯|enable MinGW native/cross Windows compile
??--enable-mingwce? ???? ?啟用MinGW本地/交叉winCE環境編譯enable MinGW native/cross WinCE compile
??--enable-a52? ???? ?? ? 啟用A52支持(默認關閉)enable GPLed A52 support [default=no]
??--enable-a52bin? ???? ? 啟用運行時打開liba52.so.0(默認關閉)open liba52.so.0 at runtime [default=no]
??--enable-dts? ???? ?? ? 啟用DTS支持(默認關閉)enable GPLed DTS support [default=no]
??--enable-pp? ?? ???? ???啟用后加工支持(默認關閉)enableGPLed postprocessing support [default=no]
??--enable-static? ???? ? 構建靜態庫(默認啟用)buildstatic libraries [default=yes]
??--disable-static? ???? ?禁止構建靜態庫(默認關閉)donot build static libraries [default=no]
??--enable-shared? ???? ? 構建共享庫(默認關閉)buildshared libraries [default=no]
??--disable-shared? ???? ?禁止構建共享庫(默認啟用)donot build shared libraries [default=yes]
??--enable-amr_nb? ???? ? 啟用amr_nbfloat音頻編解碼器|enable amr_nbfloat audio codec
??--enable-amr_nb-fixed? ? 啟用fixed amr_nb codec | use fixed point for amr-nb codec
??--enable-amr_wb? ???? ? 啟用amr_wbfloat音頻編解碼器|enable amr_wbfloat audio codec
??--enable-amr_if2? ???? ?啟用amr_wb IF2音頻編解碼器|enable amr_wb IF2 audio codec
??--enable-sunmlib? ???? ?啟用Sunmedialib(默認關閉) | use Sunmedialib [default=no]
??--enable-pthreads? ?????啟用pthreads(多線程)(默認關閉)use pthreads [default=no]
??--enable-dc1394? ???? ? 啟用libdc1394、libraw1394抓取IIDC-1394(默認關閉)enable IIDC-1394 grabbing using libdc1394 and
libraw1394 [default=no]
??--enable-swscaler? ?????啟用計數器支持?(默認關閉)softwarescaler support [default=no]
??--enable-avisynth? ?????允許讀取AVISynth腳本本件(默認關閉)allow reading AVISynth script files [default=no]
??--enable-gpl? ???? ?? ? 允許使用GPL(默認關閉)allow use of GPL code, the resulting libav* and ffmpeg will be underGPL
[default=no]
Advanced options (experts only): 高級選項參數(供專業人員使用)
??--source-path=PATH? ??? 源碼的路徑(當前為/root/flv/ffmpeg)| path to source code [/root/flv/ffmpeg]
??--cross-prefix=PREFIX? ? 為編譯工具指定路徑 | use PREFIX for compilation tools []
??--cross-compile? ???? ? 假定使用了交叉編譯 |assume a cross-compiler is used
??--cc=CC? ?? ???? ?? ?? ?指定使用何種C編譯器(默認gcc)use C compiler CC [gcc]
??--make=MAKE? ?? ???? ???使用特定的make |use specified make [make]
??--extra-cflags=ECFLAGS? ?添加ECFLAGS到CFLAGS | add ECFLAGSto CFLAGS []
??--extra-ldflags=ELDFLAGS 添加ELDFLAGS到LDFLAGS(默認-Wl,--as-needed)| add ELDFLAGS to LDFLAGS [ -Wl,--as-needed]
??--extra-libs=ELIBS? ??? 添加ELIBS | add ELIBS[]
??--build-suffix=SUFFIX? ? 為專用程序添加后綴 | suffix for application specific build []
??--arch=ARCH? ?? ???? ???選擇機器架構(默認x86)select architecture??[x86]
??--cpu=CPU? ?? ???? ?? ? 選用最低的cpu(影響指令的選擇,可以在老CPU上出錯) | selects theminimum cpu required (affects
instruction selection, may crash on older CPUs)
??--powerpc-perf-enable? ? 啟用PPC上面的性能報告(需要啟用PMC)enable performance report on PPC
? ?? ?? ???? ?? ?? ?? ???(requires enabling PMC)
??--disable-mmx? ???? ?? ?禁用MMX |disable MMX usage
??--disable-armv5te? ?????禁用armv5te | disablearmv5te usage
??--disable-iwmmxt? ???? ?禁用iwmmxt |disable iwmmxt usage
??--disable-altivec? ?????禁用AltiVec | disableAltiVec usage
??--disable-audio-oss? ???禁用OSS音頻支持(默認啟用)disable OSS audio support [default=no]
??--disable-audio-beos????禁用BeOS音頻支持(默認啟用)disable BeOS audio support [default=no]
??--disable-v4l? ???? ?? ?禁用video4linux提取(默認啟用)disable video4linux grabbing [default=no]
??--disable-v4l2? ???? ???禁用video4linux2提取(默認啟用)disable video4linux2 grabbing [default=no]
??--disable-bktr? ???? ???禁用bktr視頻提取(默認啟用)disable bktr video grabbing [default=no]
??--disable-dv1394? ???? ?禁用DV1394提取(默認啟用)disable DV1394 grabbing [default=no]
??--disable-network? ?????禁用網絡支持(默認支持)disablenetwork support [default=no]
??--disable-ipv6? ???? ???禁用ipv6支持(默認支持)disable ipv6 support [default=no]
??--disable-zlib? ???? ???禁用zlib(默認支持)disable zlib [default=no]
??--disable-simple_idct? ? 禁用simple IDCT例程(默認啟用)disablesimple IDCT routines [default=no]
??--disable-vhook? ???? ? 禁用videohooking支持 | disable videohooking support
??--enable-gprof? ???? ???enable profiling with gprof [no]
??--disable-debug? ???? ? 禁用調試符號 |disable debugging symbols
??--disable-opts? ???? ???禁用編譯器最優化 |disable compiler optimizations
??--disable-mpegaudio-hp? ?啟用更快的解碼MPEG音頻(但精確度較低)(默認禁用)faster(but less accurate) MPEG audio decoding
[default=no]
??--disable-protocols? ???禁用 I/O 協議支持(默認啟用)disable I/O protocols support [default=no]
??--disable-ffserver? ??? 禁用生成ffserver |disable ffserver build
??--disable-ffplay? ???? ?禁用生成ffplay |disable ffplay build
??--enable-small? ???? ???啟用優化文件尺寸大小(犧牲速度)optimize for size instead of speed
??--enable-memalign-hack? ?啟用模擬內存排列,由內存調試器干涉? | emulate memalign, interferes with memory debuggers
??--disable-strip? ???? ? 禁用剝離可執行程序和共享庫| disable stripping of executables and shared libraries
??--disable-encoder=NAME? ?禁用XX編碼器 | disablesencoder NAME
??--enable-encoder=NAME? ? 啟用XX編碼器 | enables encoderNAME
??--disable-decoder=NAME? ?禁用XX解碼器 | disablesdecoder NAME
??--enable-decoder=NAME? ? 啟用XX解碼器 | enables decoderNAME
??--disable-encoders? ??? 禁用所有編碼器 | disablesall encoders
??--disable-decoders? ??? 禁用所有解碼器 | disablesall decoders
??--disable-muxer=NAME????禁用XX混音器 | disables muxer NAME
??--enable-muxer=NAME? ???啟用XX混音器 | enables muxer NAME
??--disable-muxers? ???? ?禁用所有混音器 |disables all muxers
??--disable-demuxer=NAME? ?禁用XX解軌器 | disablesdemuxer NAME
??--enable-demuxer=NAME? ? 啟用XX解軌器 | enables demuxerNAME
??--disable-demuxers? ??? 禁用所有解軌器 | disablesall demuxers
??--enable-parser=NAME????啟用XX剖析器 | enables parser NAME
??--disable-parser=NAME? ? 禁用XX剖析器 | disables parserNAME
??--disable-parsers? ?????禁用所有剖析器 | disablesall parsers
8 參考資料
ffmpeg的編譯大全
ffmpeg的使用
ffmpeg_mencoder環境搭建和視頻處理總結
自譯的ffmpeg ./configure參數
?
mplayer 使用手冊(中文)
MPlayer
名稱
概要
說明
一般注記
播放選項 ( 僅用于 MPLAYER)
分路器 / 媒體流選項
OSD/ 字幕選項
音頻輸出選項 ( 僅用于 MPLAYER)
視頻輸出選項 ( 僅用于 MPLAYER)
解碼 / 濾鏡選項
編碼選項 ( 僅用于 MENCODER)
鍵盤控制
SLAVE 模式協議
文件
示例
BUGS
作者
標準聲明
名稱
mplayer ? Linux下的電影播放器
mencoder ? Linux下的電影編碼器
概要
mplayer [選項] [ 文件 | URL | 播放列表 | - ]
mplayer [全局選項] 文件1 [特定選項] [文件2] [特定選項]
mplayer [全局選項] {一組文件和選項} [針對該組的特定選項]
mplayer [dvd|vcd|cdda|cddb|tv]://title [選項]
mplayer [mms[t]|http|http_proxy|rt[s]p]:// [用戶名:密碼@]URL[:端口] [選 項]
mencoder [選項] [ 文件 | URL | - ] [?o 輸出文件]
gmplayer [選項] [?skinskin]
說明
mplayer 是一個LINUX下的電影播放器, (也能運行在許多其它的Unices 和非x86 的CPU 上, 參看文檔). 它能使用本地的, XAnim, Win32 DLL的編解碼器播放絕大 部分的MPEG/VOB, AVI, ASF/WMA/WMV, RM, QT/MOV/MP4, OGG/OGM, VIVO, FLI,NuppelVideo, yuv4mpeg, FILM 和RoQ 文件. 你還能觀看VideoCD,SVCD,DVD, 3ivx, DivX 3/4/5甚至WMV電影(不需要使用avifile庫).
MPlayer 的另一個優越的特性是對輸出設備的廣泛的支持. 它可以使 用X11, XV,DGA, OpenGL, SVGAlib, fbdev, AAlib, DirectFB, 但你也可以使用GGI, SDL(由 此可以使用他們的所有驅動),VESA(所有VESA兼容的顯卡,甚至可以 沒有X11), 某 些 低級的顯卡相關的驅動(Matrox,3Dfx和ATI)和一些硬件MPEG解碼器卡, 比 如Siemens DVB,DXR2和DXR3/Hollywood+. 它們中絕大多數支持軟件或硬件縮放, 所以你可以 享 受全屏電影.
MPlayer 具有onscreendisplay(OSD)功能, 用來顯示狀態信息, 清晰放大反鋸齒 帶陰影的字幕和鍵盤控制的視覺反饋. 支持的字體包括歐洲語種/ISO8859-1,2 ( 匈 牙 利語, 英語, 捷克語等等), 西里爾語和韓語, 可以播放10種格式的字幕文件(MicroDVD, SubRip, SubViewer, Sami, VPlayer, RT, SSA, AQTitle,JACOsub 和 我 們 自 己 的: MPsub)和DVD字幕(SPU流, VobSub和隱藏字幕數據 表(ClosedCaptions)).
mencoder (MPlayer的電影編碼器)是一個簡單的電影編碼器, 設計用來把MPlayer 可以播放的電影(見上面)編碼成另一些MPlayer可以播放的格式(見下面). 它可 以通過1, 2或者3 pass的方式編碼DivX4, XviD,libavcodec的編解碼器支持的視 頻格式和PCM/MP3/VBRMP3的音頻. 進一步的它還擁有流復制的能力, 一個強大的插件系統(crop, expand, flip, postprocess, rotate, scale, noise, rgb/yuv 轉換)和更多.
gmplayer 是使用圖形用戶界面的MPlayer.它使用跟MPlayer相同的參數.
一般注記
參見HTML文檔!
每個’flag’選項都有一個對應的’noflag’選項, 比如?fs選項的對應選項是?nofs.
你可以把所有選項放在配置文件中, mplayer每次運行時都會讀取它們. 系統范圍的配置文件’mplayer.conf’在你的配置目錄中, (比如/etc/mplayer或者/usr/local/etc/mplayer), 用戶特定的配置文件是’~/.mplayer/config’.用戶特定的選項優先于系統范圍的選項, 而命令行選項優先于這兩者. 配置文件的語法是’選項=<參數>’, ’#’后面的都認為是注釋. 啟用沒有參數的選項可以把參數設為’yes’ 或者’1’, 而如果要禁用就把它們設置為’no’或者’0’. 甚至子選項也可以通過這種方式設定.
示例:
# 默認使用Matrox驅動.
vo=xmga
# 我喜歡在看片子的時候練習倒立.
flip=yes
# 從多個png文件解碼/編碼, 以-mf啟動
mf= type=png:fps=25
你也可以制作針對特定文件的配置文件. 如果你希望’movie.avi’這個文件有自己的配置文件, 創建一個叫’movie.avi.conf’的文件, 寫上針對該文件的選項, 把它放在~/.mplayer中或者該文件同一目錄下.
播放選項 ( 僅用于 MPLAYER)
?, ?use-stdin
從標準輸入讀取數據. ?idx選項無法與這個選項同時工作.
?autoq <質量> (與?vf pp一起使用)
根據可用的CPU空閑時間動態調整后期處理的級別. 你設定的數字是允許使用的最高級別. 一般來說你可以使用一些比較大的數字. 你必須使用不帶參數的?vf pp才能使用它.
?autosync <因子>
基于音頻延遲的檢測逐步調整A/V同步. 設定?autosync 0, 也就是默 認值, 將導致幀記時完全基于音頻延遲的檢測. 設定?autosync 1也是一 樣, 但將會微妙的改變所使用的A/V修正算法. 設置大于1的值對那些視頻幀速率不均勻, 但用?nosound可以正常播放的電影一般會有幫助. 這 個值越大, 記時方法越接近于?nosound. 對于沒有好的音頻延遲檢測功 能的聲卡驅動試試用?autosync 30來平滑這個問題. 使用這個值時, 如 果出現大的A/V同步偏移, 只需要1或2秒就可以擺平. 對于任何聲卡驅動, 打開這個選項的唯一缺點就是對于突然的A/V偏移的反應延遲時間.
?benchmark
在終端顯示一些CPU使用率和丟幀數的統計信 息. 與?nosound 和?vo null聯合使用可以用來評測視頻解碼器.
?edl <文件名>
在播放時啟用編輯決定列表(EDL)的動作. 根據所給文件的內容, 可以跳 過視頻, 靜音和取消靜音. 具 體 內 容 和 使 用 方 法 參 見DOCS/documentation.html#edl.
?edlout <文件名>
建立一個新文件并寫入編輯決定列表(EDL)的記錄. 在播放時, 當用戶按 下’i’, 一個跳過下面兩秒的記錄將寫入文件. 用戶以后可以以此作為調 整EDL記錄的出發點. 具體內容參見DOCS/documentation.html#edl.
?enqueue (僅用于GUI)
將命令行中的文件加入播放序列而不是立刻播放它們.
?fixed-vo (BETA代碼!)
對多個文件使用一個固定的視頻系統(對所有文件初始化/釋放一次). 所以對所有文件只使用一個窗口, 目前fixed-vo兼容的驅 動 有: x11, xv,xvidix, xmga, gl2, and svga.
?framedrop (參見?hardframedrop)
跳過一些幀從而在慢的機器上實現A/V同步.視頻濾鏡不會應用到這些幀上. 對于B幀解碼也會完全跳過.
?h, ?help, ??help
顯示簡短的選項摘要.
?hardframedrop
丟掉更多的幀(破壞解碼). 導致圖像破損!
?identify
用容易分析的格式顯示文件參數. 調用的TOOLS/midentify腳本將濾除mplayer的其它輸出而(但愿能)留下文件名.
?input <命令>
這個選項可以用來配置輸入系統的特定部分. 路徑相對于~/.mplayer/.
注意:
自動重復功能目前只有游戲操縱桿支持.
可用的命令有:
conf=<文件>
讀取另外的input.conf. 如果沒有給出路徑名, 將假設是~/ .mplayer.
ar?delay
在開始自動重復一個鍵之前等待多少毫秒(0代表禁用).
ar?rate
當自動重復是每秒重復多少次.
keylist
列出所有可以被綁定的鍵.
cmdlist
列出所有可以被綁定的命令.
js?dev
指定可用的游戲操縱桿設備(默認為/dev/input/js0).
file
從指定文件讀取命令, 用于命名管道很有效.
?lircconf <文件>
指定LIRC(Linux Infrared Remote Control, 參見http://www.lirc.org)的配置文件, 如果你不喜歡默認的~/.lircrc的話.
?loop <數字>
重復播放電影<數字>遍. 0表示不斷重復.
?menu (BETA代碼)
打開OSD菜單支持.
?menu-root <參數> (BETA代碼)
指定主菜單.
?menu-cfg <文件> (BETA代碼)
使用另外的menu.conf.
?nojoystick
關閉游戲操縱桿的支持. 默認是只要編譯了就會打開.
?nolirc
關閉LIRC支持.
?nortc
關閉使用Linux的RTC(real-time clock? /dev/rtc)作為計時 器的功能.
?playlist <文件>
根據播放列表播放文件(每行一個文件或者Winamp或ASX格式).
?quiet
顯示較少的輸出和狀態信息.
?really?quiet
顯示更少的輸出和狀態信息.
?sdp
指定輸入文件為描述一個RTP會話 的SDP(’SessionDescription Protocol’)文件, (參見http://www.live.com/mplayer/).
?shuffle
以隨機順序播放文件.
?skin <skin目錄> (BETA代碼)
從指定目錄中裝載skin(沒有路徑名).
示例:
?skin fittyfene
嘗試Skin/fittyfene. 將 會 首 先 察 看/usr/local/share/mplayer/,然后是~/.mplayer/.
?slave
這個選項打開slave模式. 這用來將MPlayer作為其它程序的后 端. MPlayer將從他的標準輸入讀取簡單命令行, 而不再截獲鍵盤事件. SLAVE模式協議部分將解釋其語法.
?softsleep
使用高質量的軟件計時器. 跟RTC同樣精確且不需要特別權限. 代價是更 高的CPU消耗.
?speed <0.01?100>
設置播放速率.
?sstep <秒>
設定各幀顯示之間的時間間隔. 用于幻燈片播放.
分路器 / 媒體流選項
?aid <標識> (參見 ?alang選項)
選擇音頻頻道 [MPEG: 0?31 AVI/OGM: 1?99 ASF/RM: 0?127 VOB(AC3): 128?159VOB(LPCM): 160?191] MPlayer在冗長(-v)模式下會顯示可用的標識.
?alang <兩個字母的國家代碼>(參見?aid選項)
僅用于DVD播放. 它選擇DVD的音頻語言并總是嘗試播放與所給代碼符合 的語言. 加上?v參數觀察輸出可以獲得可用語言的列表.
示例:
?alang hu,en
播放匈牙利語, 英語在沒有匈牙利語時備用.
?audio?demuxer <數字> (僅用于?audiofile)
指定用于?audiofile的分路器. 分路器的標識在demuxers.h 中. 使用?audio?demuxer 17將指定.mp3檢測.
?audiofile <文件名>
在看電影時播放外部文件(WAV, MP3或Ogg Vorbis)的音頻.
-audiofile-cache <kBytes>
對-audiofile的文件流啟用緩存, 使用指定大小的內存.
?bandwidth <參數>
設定網絡流的最大帶寬(用于服務器可以以不同帶寬傳送內容的情況).當你以慢速連接觀看流媒體實況時有用.
?cdrom?device <設備路徑>
替代默認的CDROM設備名/dev/cdrom.
?cache <kBytes>
這個選項設定用多少內存(以kBytes為單位)作為播放文件/URL的預緩沖. 對速度慢的媒體特別有用(默認為?nocache).
?cdda <選項1:選項2>
這個選項用來調整MPlayer的CD音頻讀取特性.
可用選項有:
speed=<參數>
設定CD轉速
paranoia=<0?2>
設定謹慎級別
0: 關閉檢測
1: 只進行重疊檢測(默認)
2: 完全數據修正和校檢
generic-dev=<參數>
使用指定的通用SCSI設備
sector-size=<參數>
單位讀取量
overlap=<參數>
將校檢時的最小重疊搜索設置為<參數>個扇區.
toc-bias
假定TOC中報告的第1音軌的起始偏移量將按照LBA 0定位. 有些東芝光驅需要這個來獲得正確的音軌邊界.
toc-offset=<參數>
給定位音軌時在報告的扇區數上再加上<參數>個扇區. 可以是負 數.
(no)skip
(不)接受不完整的數據重建.
?channels <數字>
改變播放的聲道數, 如果沒有設定默認值為’2’. 如果輸出聲道數比輸入聲道數多時, 將插入空聲道(但在將單聲道混合為立體聲時, 會把單聲道 復 制到兩個輸出聲道). 如果輸出聲道比輸入聲道少, 結果取決與所用 的音頻解碼器(?afm).MPlayer會要求解碼器把音頻解碼到跟指定數 量的聲道. 由解碼器來實現這個要求. 如果解碼器的輸出比要求的多, 多 余的聲道會被去掉. 這個選項通常只有在播放AC3音頻(比如DVD)的視頻 時才顯得重要. 在那時默認使用liba52解碼并把音頻適當的混合到需要 的輸出聲道.
注意:
這個選項可以被解碼器(僅用于AC3)濾鏡(surround)和音頻輸出驅動( 至少OSS可以)接受.
可用選項有:
2
Stereo
4
Surround
6
Full 5.1
?chapter <場景標識>[-<結束的場景標識>]
設定從哪個場景開始播放. 也可以設定在哪個場景結束播放(默認值: 1). 示例可以在下面找到.
?csslib <文件名>
(老式DVD選項)這個選項用來替代libcss.so的默認位置.
?cuefile <文件名> (參見?vcd)
從指定的文件中描述的, CDRwin的(bin/cue文件格式)光盤 鏡 像 中 播 放(S)VCD.
?demuxer <參數>
指定分路器類型. 分路器的標識定義在demuxers.h中. 使用?demuxer 17將指定.mp3檢測.
?dumpaudio (僅用于MPLAYER)
將原始的音頻壓縮流復制到./stream.dump(用于mpeg/ac3).
?dumpfile <文件名> (僅用于MPLAYER)
指定MPlayer復制的輸出文件. 應該與?dumpaudio / ?dumpvideo / ?dumpstream一起使用.
?dumpstream (僅用于MPLAYER)
將原始流復制到./stream.dump. 當從DVD或網絡上rip時候有用.
?dumpvideo (僅用于MPLAYER)
將原始的視頻壓縮流復制到./stream.dump(不是十分好用).
vd://<節目標識>
告訴MPlayer播放哪個電影(通過節目標識指定). 比如有時’1’是一部預告片, 而’2’才是真正的電影.
注意:
有時DVD播放時需要進行交錯/逐行掃描轉換, 參見?vf pp=0x20000選項.
?dvd?device <設備路徑>
替代默認的DVD設備名/dev/dvd.
?dvdangle <視角標識>
有些DVD 碟 片中的場景可以從多個視角觀看. 通過這個選項你可以告 訴MPlayer使用那個視角(默認值: 1). 示例可以在下面找到.
?dvdauth <DVD設備>
(老式DVD選項)打開指定設備的DVD認證.
?dvdkey <CSS密鑰>
(老式DVD選項)當解碼一個由DVD上復制的未解密的VOB文件時, 用這個選項提供解碼VOB需要的CSS密鑰(密鑰在?dvdauth通過DVD設備認證時會顯 示出來).
?dvdnav (BETA代碼!)
強行使用libdvdnav.
?forceidx
指定重新生成索引. 對索引損壞的文件(不同步等等)有用. 可以進行收縮. 你能使用MEncoder永久性的修復索引(參見文檔).
?fps <參數>
替代幀速率(如果文件頭中沒有該參數/參數是錯誤的)(浮點數).
?frames <參數>
只播放/轉換前<參數>幀, 然后退出.
?hr?mp3?seek (僅用于MP3)
高精度mp3搜索. 默認為: 在播放外部MP3文件時啟用, 因為我們需要搜 索到非常精確的位置來保持A/V同步. 這種方法在后退搜索時特別 慢 ? 它需要繞回開頭來找到準確的幀.
?idx (參見?forceidx)
在沒有找到索引的情況下重建AVI文件的索引, 從而允許搜索. 對于損 壞的/不完整的下載, 或制作低劣的AVI.
?mc <每幀秒數>
每幀的最大A-V同步修正(以秒為單位).
?mf <選項1:選項2:...>
用來從多個PNG或JPEG文件解碼.
可用選項有:
on
打開多文件支持
w=<參數>
輸出的寬度(自動檢測)
h=<參數>
輸出的高度(自動檢測)
fps=<參數>
輸出的幀速率(默認值: 25)
type=<參數>
輸入文件的類型(可用類型: jpeg, png, tga,sgi)
?ni (僅用于AVI)
指定使用非交錯的AVI分析器(用來處理某些質量差的AVI文件的播放).
?nobps (僅用于AVI)
不使用平均比特率值來維持A?V同步(AVI). 對某些文件頭損壞的AVI文件 有幫助.
?noextbased
禁用基于后綴名的分路器選擇機制. 默認情況下, 當文件類型(分路器) 無法可靠檢測時, (文件沒有頭部或者不夠可靠), 將使用后綴名來選擇分路器. 后備的基于內容的分路器總是可用的.
?passwd <密碼> (參見?user選項)
設置http認證的密碼.
?rawaudio <選項1:選項2:...>
用這個選項你可以播放原始音頻文件. 也可以用來播放不是44KHz 16Bit立體聲的音頻CD.
可用選項有:
on
使用原始音頻分路器
channels=<參數>
聲道數
rate=<參數>
每秒采樣率
samplesize=<參數>
以字節為單位的樣本大小
format=<參數>
16進制的fourcc
?rawvideo <選項1:選項2:...>
用這個選項你可以播放原始視頻文件.
可用選項有:
on
使用原始視頻分路器
fps=<參數>
每秒幀速率, 默認值為25.0
sqcif|qcif|cif|4cif|pal|ntsc
設置默認的圖像大小
w=<參數>
以像素為單位的圖像寬
h=<參數>
以像素為單位的圖像高
y420|yv12|yuy2|y8
設置色彩空間
format=<參數>
16進制的色彩空間(fourcc)
size=<參數>
以字節為單位的幀大小
?rtsp-stream-over-tcp
與’rtsp://’URL一起用來指定最后結果輸入的RTP和RTCP的包通過TCP流, (跟RTSP使用同一個TCP連接 ). 這個選項可以用于當你的Internet連接不允許UDP包進入的情況. (參見http://www.live.com/mplayer/).
?skipopening
提過DVD打開(僅用于dvdnav).
?sb <比特位置> (參見?ss選項)
搜索到比特位置. 用于播放開始部分是垃圾的CDROM鏡像/.VOB文件.
?srate <Hz>
指定音頻播放速, 視頻播放速度也會改變以保持a-v同步. MEncoder 會 把這個值傳給lame用于重新采樣.
?ss <時間> (參見?sb選項)
搜索到指定的時間位置.
示例:
?ss 56
搜索到56秒處
?ss 01:10:00
搜索到1小時10分鐘處
?tv <選項1:選項2:...>
這個選項會啟用MPlayer的電視截取功能.
注意:
MPlayer 不 接受冒號所以在設備標識中用逗號代替. (例如.用hw.0,0代 替hw:0,0).
雖然使用ALSA是你可以選擇任何采樣率, 但LAME音頻編碼器只能 對’ 標準’ 的采樣率進行編碼. 如果你選擇一個奇怪的采樣率使用這個編碼器得到的.avi文件會沒有聲音.
可用選項有:
on
使用電視輸入
noaudio
沒有聲音
driver=<參數>
可用參數: dummy, v4l, bsdbt848
device=<參數>
設定默認的/dev/video0之外的設備
input=<參數>
設定默認的0(電視)之外的輸入(參見輸出的列表)
freq=<參數>
設定電視調諧器的頻率(例如 511.250). 與頻道參數不兼容.
outfmt=<參數>
電視調諧器的輸出格式(yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2, i420)
width=<參數>
輸出窗口的寬度
height=<參數>
輸出窗口的高度
fps=<參數>
捕捉視頻的幀速率(幀每秒)
buffersize=<參數>
設定以兆為單位的捕捉緩沖區的大小(默認值: 動態)
norm=<參數>
可用參數: PAL, SECAM, NTSC
channel=<參數>
把電視調諧器設定到<參數>頻道.
chanlist=<參數>
可用參數: europe-east, europe-west, us-bcast, us-cable, 等等
channels=<頻道>?<名稱>,<頻道>?<名稱>,...
設定頻道的名稱. 在名稱中用_代替空格(或者玩引號 游 戲. 頻 道 名 稱 會用OSD顯示, tv_step_channel, tv_set_channel 和tv_last_channel等命令將可以被遙控器(參見lirc)使用. 與頻率參數不兼容. 警告: 頻道編號將出現在’頻道’列表上, 從1 開始. 示例: 使用tv://1,tv://2, tv_set_channel1, tv_set_channel 2等等.
[brightness|contrast|hue|saturation]=<?100?100>
設置顯卡的色彩均衡器.
audiorate=<參數>
設定音頻捕捉比特率
forceaudio
即使v4l報告沒有音頻源也捕捉音頻
alsa
從ALSA捕捉
amode=<0?3>
選擇音頻模式:
0: mono
1: stereo
2: language 1
3: language 2
forcechan=<1?2>
默認情況下, 記錄音頻聲道數由電視卡檢察音頻模式自動決定.這個選項允許指定立體聲/單聲道記錄而不管amode選項和v4l 返 回 的參數. 在電視卡不能報告正確的音頻模式的時候可以用這個選項解決麻煩.
adevice=<參數>
設置音頻設備
/dev/...用于OSS
硬件標識用于ALSA
audioid=<參數>
選擇捕捉卡的音頻輸出, 如果它有不止一個的話
[volume|bass|treble|balance]=<0?65535>
這些選項用來設定視頻捕捉卡上的混音器參數. 如果你的卡 沒 有混音器, 它們將沒有效果.
immediatemode=<布爾值>
參數值為0表示同時捕捉和緩沖音頻和視頻(mencoder的默認值). 參數值為1(mplayer的默認值)表示只捕捉視頻而讓音頻通過通過 環路電纜由電視卡輸入聲卡.
mjpeg
使用硬件mjpeg壓縮(如果芯片支持的話). 當使用這個選項的時 候, 你不需要設置輸出窗口的寬和高, mplayer會根據抽樣參數( 見下面)自動確定.
decimation=<1,2,4>
選擇硬件mjpeg壓縮的圖像的尺寸:
1: 全尺寸 704x576PAL 704x480 NTSC
2: 中等尺寸 352x288PAL 352x240 NTSC
4: 小尺寸 176x144PAL 176x120 NTSC
quality=<0-100>
選擇jpeg壓縮的質量
(全尺寸推薦使用quality< 60)
?user <用戶名> (參見?passwd選項)
設定http認證的用戶名.
://<音軌>
從設備或鏡像文件中播放video CD音軌(參見?cuefile).
?vid <標識>
選擇視頻頻道[MPG: 0?15 ASF: 0?255].
?vivo <子選項> (調試代碼)
指定.vivo分路器的音頻參數(用于調試).
OSD/ 字幕選項
注意:
參見?vf expand.
?dumpmicrodvdsub (僅用于MPLAYER)
把給定的字幕文件(由?sub選項設置)轉換為MicroDVD字幕格式. 在當前 目錄中創建一個dumpsub.sub文件.
?dumpmpsub (僅用于MPLAYER)
把給定的字幕文件(由?sub選項設置)轉換為MPlayer的字幕格式, MPsub. 在當前目錄中創建一個dump.mpsub文件.
?dumpsrtsub (僅用于MPLAYER)
把給定的字幕文件(由?sub選項設置)轉換為基于時間的SubViewer(SRT)字幕格式. 在當前目錄中創建一個dumpsub.srt文件.
?dumpjacosub (僅用于MPLAYER)
把給定的字幕文件(由?sub選項設置)轉換為基于時間的JACOsub字幕格式. 在當前目錄中創建一個dumpsub.js文件.
?dumpsami (僅用于MPLAYER)
把給定的字幕文件(由?sub選項設置)轉換為基于時間的SAMI字幕格式. 在當前目錄中創建一個dumpsub.smi文件.
?dumpsub (僅用于MPLAYER)(BETA代碼)
從VOB流中復制子字幕流. 參見-dump*sub和-vobsubout*選項.
?ifo <vobsub的ifo文件>
設置用于讀取的包含VOBSUB字幕的調色板和幀尺寸的文件.
?ffactor <數字>
對字體的alpha映射圖重新采樣. 可設為:
0
普通白色字體
0.75
非常細的黑色邊框(默認值)
1
細的黑色邊框
10
粗的黑色邊框
?font <font.desc文件的路徑>
在另外目錄你尋找OSD/SUB字體(默認的普通字體為: ~/.mplayer/font/ font.desc, 默認的FreeType字體為: ~/.mplayer/subfont.ttf).
注意:
對于FreeType, 這個選項指定文本字體文件的路徑.
?subfont-*選項只有當編譯了FreeType支持才可用.
示例:
?font ~/.mplayer/arial?14/font.desc
?font ~/.mplayer/arialuni.ttf
?noautosub
關閉字幕文件的自動載入功能.
?overlapsub
對所有字幕格式啟用重疊字幕支持.
?nooverlapsub
對所有字幕格式禁用重疊字幕支持(默認行為是只對特定格式啟用支持).
?osdlevel <0?3> (僅用于MPLAYER)
設定開始的OSD模式.
0
只有字幕
1
音量 + 搜索(默認)
2
音量 + 搜索 + 計時器 + 百分比
3
音量 + 搜索 + 計時器 + 百分比 + 總時間
?sid <標識> (參見?slang選項)
打開DVD字幕顯示. 同時, 你必須設置一個對應于一種DVD字幕語言的數字(0?31). 至于可用字幕的列表, 可以加上?v選項并察看輸出.
?slang <兩個字母的國家代碼>(參見?sid選項)
僅用于DVD播放. 打開/選擇DVD字幕語言. 至于可用字幕的列表, 可以加上?v選項并察看輸出.
示例:
?slang hu,en
選擇匈牙利語, 英語在沒有匈牙利語時備用.
?sub <字幕文件>
使用/顯示指定的字幕文件.
?sub-bg-alpha <0?255>
設置字幕和OSD背景的alpha通道值. 值越大代表越透明. 0是一個例外代表完全透明.
?sub-bg-color <0?255>
設置字幕和OSD背景的顏色值. 目前字幕是灰度圖像所以這個值相當于顏色的亮度. 255代表白色0代表黑色.
?subcc 顯示DVD的隱藏字幕數據表(CC)字幕.
它們不是VOB字幕, 它們是為聽力障礙的人準備的特殊的ASCII字幕, 編碼在大多數區碼為1的VOB的用戶數據流中. CC字幕到目前為止還沒有在 別的區碼的DVD中發現.
?subcp <編碼頁>
如果你的系統支持iconv(3), 你可以用這個選項來設置字幕文件的編 碼頁.
示例:
?subcp latin2
?subcp cp1250
?sub?demuxer <數值> (BETA代碼)
指定?subfile的字幕分路器的類型.
?subdelay <參數>
字幕延遲<參數>秒. 可以是負數.
?subfont-autoscale <0?3>
設置自動縮放模式.
注意:
0表示text-scale和osd-scale的參數為以點為尺寸的字體高度.
可用模式有:
0
不自動縮放
1
按電影高度縮放
2
按電影寬度縮放
3
按電影對角線縮放(默認值)
?subfont-blur <0?8>
設置字體模糊半徑(默認值: 2).
?subfont-encoding <參數>
設置字幕編碼. 當設為’unicode’時, 字體文件中的所有字模都會被渲染 并使用unicode編碼(默認值: unicode).
?subfont-osd-scale <0?100>
設置osd元素的自動縮放系數(默認值: 6).
?subfont-outline <0?8>
設置字體邊框的寬度(默認值: 2).
?subfont-text-scale <0?100>
設置字幕文本的自動縮放系數(屏幕尺寸的百分比) (默認值: 5).
?subfps <速率>
設置字幕文件的幀/秒速率(浮點數), 默認值: 與電影同樣的fps.
注意:
僅用于基于幀的SUB文件, 比如不能用于MicroDVD格式.
?subfile <文件名> (BETA代碼)
目前沒有用. 與?audiofile一樣, 但用于字幕流(OggDS?).
?subpos <0?100> (用于?vf expand)
設置字幕在屏幕上顯示的位置. 參數表示字幕的垂直位置位于屏幕的 百分之多少.
?subalign <0?2>
設置字幕相對于subpos如何對齊. 0表示頂部對齊(最初的/默認的行為), 1表示中央對齊, 而2標識底部對齊.
?subwidth <10?100>
設置字幕在屏幕上顯示的最大寬度. 對于電視輸出有用. 參數表示字幕寬度占屏幕寬度的百分之多少.
?unicode
告訴MPlayer以UNICODE格式處理字幕.
?utf8
告訴MPlayer以UTF8格式處理字幕.
?sub-no-text-pp
禁用載入字幕后的任何形式的文字后期處理. 用于調試.
?vobsub <無后綴名的vobsub文件名>
設置用于字幕顯示的VobSub文件. 這是無后綴名的完整路徑名, 例如沒 有’.idx’,′.ifo’或者’.sub’.
?vobsubid <0-31>
設置VobSub字幕標識.
?spualign <-1?2>
設置spu(DVD/VobSub)字幕如何對齊. 參數值與-subpos相同, 特別的, -1表示在初始位置顯示.
?spuaa <模式>
設置DVD/VobSub的反鋸齒/縮放模式. 加上16可以在原始和縮放幀尺寸完全相同時強制進行縮放, 比如使用高斯模糊來平滑字幕. 可用模式有:
0
不縮放(最快, 很丑)
1
近似縮放(好像壞了?)
2
完全縮放(慢)
3
二次線性縮放(默認值, 快速而且效果不壞)
4
使用軟件縮放的高斯模糊(看起來很好)
?spugauss <0.0?3.0>
-spuaa 4使用的高斯模糊的可變參數.越高表示越模糊. 默認值為1.0.
音頻輸出選項 ( 僅用于 MPLAYER)
?abs <參數> (已被放棄)
替代音頻驅動/聲卡的緩沖區大小檢測, 僅用于?ao oss
?af <濾鏡1[=選項],濾鏡2,...>
激活一個逗號分隔的帶參數的音頻濾鏡列表.
可用濾鏡有:
resample[=srate[:sloppy][:type]]
將音頻流的采樣率變為整數值srate(Hz). 它只支持16 bit低位在前格式.
channels[=nch]
將聲道變為nch個輸出聲道. 如果輸出聲道數比輸入聲道數多時, 將插入空聲道(但在將單聲道混合為立體聲時, 會把單聲道復 制 到兩個輸出聲道). 如果輸出聲道數比輸入聲道數少, 多余的聲 道會被去掉.
format[=bps,f]
選擇插件層輸出格式為f, 樣本比特率為bps. 選項bps是一個整 數表示每個樣本的字節數. 格式f是下面幾個字符串的連接:
alaw, mulaw或imaadpcm
float或int
unsigned或signed
le或be(低位或高位在前)
volume[=v:sc]
選擇輸出音量級別.這個選項是不可重入的, 所以對每個音頻流只能使用一次.
v: 對流中所有聲道的增益, 以dB為單位. 增益可以從-200dB 到+40dB(-200dB 完全靜音completely而+40dB等于放大1000 倍).
sc: 啟用軟修飾.
pan[=n:l01:l02:..l10:l11:l12:...ln0:ln1:ln2:...]
任意混合聲道, 細節參見DOCS/sound.html.
n: 輸出聲道數(1 - 6).
lij: 輸出聲道i中混合多少輸入聲道j的成分.
sub[=fc:ch]
增加副低音聲道.
fc: 低通濾波器的剪除頻率(20Hzto 300Hz)默認值為60Hz.
ch: 副聲道的聲道號.
surround[=d]
矩陣編碼的環繞音效解碼器, 能用于許多2聲道文件.
d: 以毫秒為單位的后部揚聲器的延遲時間(0ms到1000ms), 默認值為15ms.
delay[=ch1:ch2:...]
延遲聲音的輸出. 以百萬分之一秒為單位設置每個聲道的延遲(0到1000之間的浮點數).
?af-adv <force=(0?3):list=(filters)> (參見?af選項)
設置高級音頻濾鏡選項:
force=<0-3>
將插入音頻濾鏡的方式指定為下面之一:
0: 完全自動插入濾鏡(默認)
1: 速度優化
2: 精度優化
3: 關閉自動插入
list=<濾鏡>
與?af相同(參見?af選項).
?ao <驅動1[:設備],驅動2,...[,]>
設置可用的音頻輸出驅動的優先級列表(可以加上設備). ′設備’ 也 用 于SDL, 那里它表示子驅動.
注意:
要獲得完整的可用驅動列表, 參考?ao help.
如果列表結尾有一個’,’ 它將可以使用沒有列出的驅動作為后備.
示例
?ao oss:/dev/dsp2,oss:/dev/dsp1,
嘗試使用指定聲音設備的OSS而把其它設置作為后備
?ao sdl:esd
設置SDL的子驅動
?aofile <文件名>
用于?ao pcm的文件.
?aop <list=插件1,插件2...:選項1=參數1:選項2=參數2...>
設置音頻插件和他們的選項(參見文檔).
可用選項有:
list=[插件]
逗號分隔的插件列表(resample, surround, format, volume, extrastereo, volnorm)
delay=<秒>
插件例子, 沒有用
format=<格式>
輸出格式(僅用于format插件)
fout=<Hz>
輸出頻率(僅用于resample插件)
volume=<0?255>
音量(僅用于volume插件)
mul=<參數>
立體聲系數(默認值: 2.5)(僅用于extrastereo插件)
softclip
使用’軟修飾’壓縮功能(僅用于volume插件)
?delay <秒>
以秒為單位延遲音頻(可以是+/?浮點值).
?format <0?8192>
選擇濾鏡層使用的輸出格式 (依據libao2/afmt.h中的定義):
1
Mu-Law
2
A-Law
4
Ima-ADPCM
8
Signed 8-bit
16
Unsigned 8-bit
32
Unsigned 16-bit (低位優先)
64
Unsigned 16-bit (高位優先)
128
Signed 16-bit (低位優先)
256
Signed 16-bit (高位優先)
512
MPEG (2)音頻
1024
AC3
4096
Signed 32-bit (低位優先)
8192
Signed 32-bit (高位優先)
?mixer <設備>
這個選項讓MPlayer使用/dev/mixer之外的設備進行混音.
?nowaveheader (僅用于-ao pcm)
不包括wave文件頭. 用于原始RAW PCM.
視頻輸出選項 ( 僅用于 MPLAYER)
?aa* (僅用于?vo aa)
你可以運行 mplayer ?aahelp 來獲得一份可用選項的解釋的列表.
?bpp <深度>
使用與自動檢測結果不同的顏色深度. 不 是 所 有?vo 驅動都支持它(fbdev, dga2, svga, vesa).
?brightness <?100?100>
調整視頻輸出的亮度(默認值為0). 它改變視頻信號中RGB組份的亮度, 從黑到白.
?contrast <?100?100>
調整視頻輸出的對比度(默認值為0). 工作方式與brightness差不多.
?dfbopts <參數> (僅用于?vo directfb2)
設置directfb驅動的參數列表.
?display <name>
設置你希望使用的X server的hostname和display number.
示例:
?display xtest.localdomain:0
?double
啟用雙緩沖. 通過在內存里儲存兩幀來解決閃爍問題, 在顯示一幀的同時解碼另一幀. 會影響OSD. 需要單一緩沖方式兩倍的內存. 所以不能 用于顯存很少的顯卡.
?dr
打開直接渲染功能(不是所有的編解碼器和視頻輸出都支持)(默認為關閉). 警告: 可能導致OSD/字幕損壞!
?dxr2 <選項1:選項2:...>
這個選項用來控制dxr2驅動. 注意: 現在當你播放非MPEG1/2格式時lavc 濾鏡會自動插入, 所以現在所有MPlayer支持的格式都可以播放(如果你有實時編碼所需要的CPU速度). dxr2的疊加芯片的質量相當差不過默認設置應該可以用于每一個人. OSD可能可以通過使用colorkey的繪制方法在疊加(不能用于TV)輸出中實現. 使用默認的colorkey設定你可能獲得各種效果, 一般情況下你可能看到colorkey環繞在字符周圍或者其它可笑的效果. 但只要你適當的調節colorkey的設定你應該可以獲得可接受的效果.
ar-mode=<參數>
長寬比模式(0 = 普通, 1 = pan scan模式, 2 = letterbox 模 式(默認))
iec958?encoded/decoded
iec958輸出模式
mute
聲音輸出靜音
ucode=<參數>
microcode的路徑
TV Out
75ire
啟用7.5IRE
bw
黑白電視輸出
color
彩色電視輸出
interlaced
交錯電視輸出
macrovision=<參數>
macrovision 模 式(0 = 關閉(默認值), 1 = agc, 2 =agc 2 colorstripe, 3 = agc 4 colorstripe)
norm=<參數>
電視制式(ntsc(默認),pal,pal60,palm,paln,palnc)
square/ccir601?pixel
電視像素模式
疊加
cr-[left|right|top|bot]=<?20?20>
調整疊加裁減
ck-[rgb]min=<0?255>
color key參數最小值
ck-[rgb]max=<0?255>
color key參數最大值
ck-[rgb]=<0?255>
color key參數
ignore?cache
不使用VGA緩存
ol-osd
啟用疊加模式的osd hack
ol[hwxy]?cor=<參數>
調整疊加尺寸和位置, 如果它跟窗口匹配不夠完美
overlay
啟用疊加
overlay-ratio=<1?2500>
調整疊加模式(默認值為1000)
update?cache
重建VGA緩存
?fb <設備> (僅用于fbdev或者DirectFB)
設置使用的幀緩沖設備. 默認為/dev/fb0.
?fbmode <模式名> (僅用于fbdev)
把視頻模式設為/etc/fb.modes中標記為<模式名>的模式
注意:
VESA幀緩沖不支持改變顯示模式.
?fbmodeconfig <文件名> (僅用于fbdev)
使用這個配置文件取代默認的/etc/fb.modes. 只對fbdev驅動有效.
?forcexv (僅用于SDL)
指定使用XVideo.
?fs
全屏播放(電影顯示在中央, 四周填充黑色條邊). 用’f’鍵觸發( 不是所有的視頻輸出都支持它). 參見?zoom.
?fsmode-dontuse <0-31> (已放棄) (使用?fs選項)
如果你還有全屏問題試試這個選項.
?fstype <type1,type2,...>
設置可用的全屏層設置模式的優先級列表.
默認的次序是"layer,stays_on_top,above,fullscreen". 如果設置的模式不正確或不支持會使用后備項.
如果你遇到全屏窗口被別的窗口覆蓋的問題試試設置不同的順序.
注意:
參考?fstype help列出的全部可用模式的列表.
?geometry x[%][:y[%]] or [WxH][+x+y]
調整屏幕輸出的初始位置. x和y代表從屏幕右上角到顯示圖像右上角的距離, 以像素為單位. 不過如果在參數后有百分號記號它將把參數理解為該方向上的屏幕尺寸比例. 它也支持標準的X ?geometry的標準選項格式. 參數必須為整數.
注意: 這個選項只有一個vo支持: xv.
示例:
50:40
把窗口放在x=50, y=40處
50%:50%
把窗口放在屏幕中央
100%
把窗口放在屏幕左上角
100%:100%
把窗口放在屏幕左下角
?guiwid <窗口標識>
這告訴GUI 也使用一個X11窗口并把自己粘到視頻窗口的下方, 在將一 個mini-GUI嵌入到瀏覽器時(比如mplayer插件)有用.
?hue <?100?100>
調整視頻信號的色相(默認: 0). 你可以通過這個選項得到負片效果的圖像.
?icelayer <0?15> (僅用于icewm)
設置icewm下mplayer的全屏窗口層.
0
Desktop
2
Below
4
Normal
6
OnTop
8
Dock
10
AboveDock
12
Menu (默認)
?jpeg <選項1:選項2:...> (僅用于?vo jpeg)
設置JPEG輸出的選項.
可用選項有:
[no]progressive
設置標準的或漸進的JPEG.
[no]baseline
設置是否使用基線.
optimize=<參數>
優化因子[0-100]
smooth=<參數>
平滑因子[0-100]
quality=<參數>
質量因子[0-100]
outdir=<參數>
保存JPEG文件的目錄
?monitor_dotclock <dotclock (or pixelclock) range> (僅用于fbdev和vesa)
察看etc/example.conf和DOCS/video.html來進一步了解信息.
?monitor_hfreq <水平頻率范圍> (僅用于fbdev和vesa)
?monitor_vfreq <垂直頻率范圍> (僅用于fbdev和vesa)
?monitoraspect <長寬比>
設置你的顯示器或電視屏幕的長寬比, 參見用于電影長寬比的?aspect選項.
示例:
?monitoraspect 4:3或者1.3333
?monitoraspect 16:9或者1.7777
?nograbpointer
VidMode改變(?vm)后不截獲鼠標焦點, 用于多輸出頭設置.
?nokeepaspect
縮放X11 窗 口 時 不 保持窗口的長寬比(只工作于?vo x11, xv, xmga 和xvidix而且你的窗口管理器必須理解window aspect hints.).
?noslices
禁用把視頻分隔成16像素高的條/帶繪制的方式, 而是一次繪制整個 幀. 可能更快或更慢, 取決于顯卡/緩存. 它只對libmpeg2和libavcodec編 解碼器有效.
?panscan <0.0?1.0>
啟用Pan & Scan功能, 也就是為了在4:3的顯示器上顯示16:9, 把電影的邊緣切掉來獲得4:3的, 與屏幕匹配的圖像的方法. 這個功能只能用 于xv, xmga, mga和xvidix視頻輸出驅動.
參數用來控制切掉多少圖像.
?rootwin
在根窗口(桌面背景)中播放電影而不是重新打開一個新窗口. 只 能 用 于x11, xv,xmga和xvidix驅動.
?saturation <?100?100>
調整視頻輸出的飽和度(默認值: 0). 你可以通過這個選項獲得灰度輸出.
?screenw <像素>?screenh <像素>
如果你使用的輸出驅動無法獲得屏幕分辨率(fbdev/x11和/或者 TVout) ,你可以在這里設置水平和垂直分辨率.
?stop_xscreensaver
在啟動是關閉xscreensaver在退出時再打開它.
?vm
嘗試改變到更合適的視頻模式. dga, x11/xv (XF86VidMode)和sdl 輸出驅動支持.
?vo <驅動1[:設備],驅動2,...[,]>
設置可用的視頻輸出驅動的優先級列表(可以加上設備). ′設備’ 也 用 于SDL和GGI, 那里它表示子驅動.
注意:
要獲得完整的可用驅動列表, 參考?vo help.
如果列表結尾有一個’,’ 它將可以使用沒有列出的驅動作為后備.
示例:
?vo xmga,xv,
先嘗試Matrox內核驅動, 然后Xv驅動, 然后其它
?vo sdl:aalib
設置SDL子驅動
?vsync
啟用vesa的VBI支持.
?wid <窗口標識>
告訴MPlayer 使 用 一 個X11窗口, 在把MPlayer嵌入瀏覽器是有用(比 如plugger擴展).
?xineramascreen <0?...>
在Xinerama配置時,(就是一個單一桌面展開在多個顯示器上),這個 選 項告訴MPlayer把電影顯示在哪個屏幕上.
?z <0?9>
設置PNG輸出的壓縮級別(僅用于?vo png)
0
不壓縮
9
最大壓縮
?zrbw (僅用于?vo zr)
黑白顯示(用于優化性能, 這個選項可以跟屬于FFmpeg家族的編解碼器 的’黑白解碼’的選項聯合使用).
?zrcrop <[寬]x[高]+[x偏移]+[y偏移]> (僅用于?vo zr)
選擇顯示輸入圖像的一部分, 使用多個這樣的選項就啟動了cinerama模式. 在cinerama模式下電影分布在多個電視(或投影儀)來創造一個更大的屏幕. 在第n個?zrcrop后面的選項應用于第n個MJPEG解碼卡, 每一個編碼卡至少需要有一個?zrcrop選項加上一個?zrdev選項. 察看?zrhelp 的輸出和文檔的Zr部分可以找到示例.
?zrdev <設備> (僅用于?vo zr)
設置你的MJPEG編碼卡使用的設備文件名, 默認情況下這個驅動將使用它找到的第一個v4l設備.
?zrfd (僅用于?vo zr)
指定使用簡化取樣: 簡化取樣由?zrhdec和?zrvdec設置, 一般只有在硬件縮放能把圖像延展到原始尺寸時才使用. 使用這個選項指定使用簡 化取樣.
?zrhelp (僅用于?vo zr)
顯示所有?zr*選項列表, 他們的默認值和使用cinerama模式的例子.
?zrnorm <制式> (僅用于?vo zr)
設置制式為PAL/NTSC, 默認值為’不改變’
?zrquality <1?20> (僅用于?vo zr)
從1到20的數值代表jpeg編碼質量. 1的質量最好而20的質量非常差.
?zrvdec <1,2,4> ?zrhdec <1,2,4> (僅用于?vo zr)
垂直/水平簡化取樣: 驅動只會把輸入圖像的每2或4行/點發送到MJPEG編碼卡, 而使用MJPEG卡的縮放器把圖像回復到原有尺寸.
?zrxdoff <x顯示位移>,?zrydoff <y顯示位移> (僅用于?vo zr)
如果電影比電視屏幕小, 這些選項控制電影相對于屏幕左上角的顯示 位置. 默認情況下電影放在中央位置.
解碼 / 濾鏡選項
?ac <[-]編解碼器1,[-]編解碼器2,...[,]>
設置可用編解碼器的優先級列表, 按照它們在codecs.conf中的編解碼器名稱. 在名稱前加’-’表示忽略該編解碼器.
注意:
全部可用編解碼器的完整列表參見?ac help的輸出.
如果列表結尾有一個’,’ 將可以使用沒有列出的編解碼器作為后備.
示例:
?ac mp3acm
指定使用l3codeca.acm MP3編解碼器
?ac mad,
先嘗試libmad, 其它作為后備
?ac hwac3,a52,
先嘗試硬件AC3輸出, 然后是軟件AC3編解碼器, 最后是其它
?ac -ffmp3,
嘗試除了FFmpeg的MP3解碼器之外的所有解碼器
?afm <驅動1,驅動2,...>
設置可用的音頻驅動優先級列表, 按照它們在codecs.conf中的驅動名稱. 當都不可用是使用默認后備驅動.
注意:
全部可用編解碼器的完整列表參見?afm help的輸出.
示例:
?afm ffmpeg
先嘗試FFmpeg的libavcodec(mp1/2/3)編解碼器
?afm acm,dshow
先嘗試Win32編解碼器
?aspect <比率>
設置電影的長寬比. MPEG文件會自動檢測, 但大多數AVI文件不會.
示例:
?aspect 4:3或?aspect1.3333
?aspect 16:9或?aspect1.7777
?flip
上下翻轉圖像.
?lavdopts <選項1:選項2:...> (調試代碼)
如果使用libavcodec解碼, 你可以在這里設置參數.
示例:
?lavdopts bug=1
注意:
只要加上你想要啟用的項目的參數即可.
可用選項有:
ec
錯誤隱藏:
1: 對損壞的MB使用強柔化馬賽克濾鏡
2: MV重復搜索(很慢)
3: 所有(默認)
er=<參數>
錯誤恢復:
0: 禁用
1: 小心 (用于損壞的編碼器)
2: 正常 (默認) (用于正常的編碼器)
3: 擴張性的 (更多檢查但可能即使對有效比特流也導致問題)
4: 非常擴張性的
bug=<參數>
手工繞過編碼器bug:
0: 無
1: 自動檢測bugs (默認)
2 (msmpeg4v3): 由老式lavc生成的msmpeg4v3文件(不自動檢測)
4 (mpeg4): xvid交錯bug(如果fourcc==XVIX會自動檢測)
8 (mpeg4): UMP4(如果fourcc==UMP4會自動檢測)
16 (mpeg4): padding bug(自動檢測)
32 (mpeg4): 非法vlc bug(每個fourcc都自動檢測)
64 (mpeg4): XVID和DIVX qpel的bug(每個fourcc/版本都自動檢測)
128 (mpeg4): 老的標準的qpel(每個fourcc/版本都自動檢測)
256 (mpeg4): 另一個qpel的bug(每個fourcc/版本都自動檢測)
512 (mpeg4): direct-qpel-blocksize的bug(每個fourcc/ 版本都自動檢測)
1024 (mpeg4): edge padding的bug(每個fourcc/版本都自動檢測)
idct=<0?99>
(參見lavcopts) 想要最好的解碼質量應該在編碼和解碼時使用相同的idct算法. 不過這可能會犧牲一些精確性.
gray
只解碼灰度圖像(比彩色解碼快一點)
?noaspect
禁用電影長寬比自動嘗試.
?nosound
不播放/編碼聲音.
?pp <質量> (參見?vf pp選項!)
設置DLL的后期處理級別. 這個選項不能用于MPlayer的后期處理濾鏡, 但可以用于有內部后期處理例程的Win32 DirectShow DLL.
?pp的參數范圍依編解碼器不同,大部分為0?6, 0=禁用 6=最慢/最好.
?pphelp (參見?vf pp選項)
列出可用后期處理濾鏡和他們的使用方法簡介.
?ssf <mode>
設置SwScaler參數.
示例
?vf scale ?ssf lgb=3.0
lgb=<0?100>
高斯模糊濾鏡(亮度)
cgb=<0?100>
高斯模糊濾鏡(色度)
ls=<0?100>
銳化濾鏡(亮度)
cs=<0?100>
銳化濾鏡(色度)
chs=<h>
水平色度偏移
cvs=<v>
垂直色度偏移
?stereo <模式>
選擇MP2/MP3立體聲輸出模式.
0
立體聲
1
左聲道
2
右聲道
?sws <軟件縮放類型> (參見?vf scale選項)
這個選項用來設置?zoom選項使用的軟件縮放的質量(還有速度, 相 對 的). 用于x11或其它沒有硬件加速的視頻輸出. 可用選項有:
注意:
對于?sws 2和7, 可以用?vf scale的縮放參數(p)來設置銳化(0(柔化) ? 100(銳化)), 對于?sws 9, 這個參數設置濾鏡長度參數(1 ? 10).
0
快速二次線性(默認)
1
二次線性
2
二次立方(質量很好)
3
實驗中
4
最短距離 (bad quality)
5
區域
6
亮度二次立方/色度二次線性
7
高斯
8
sincR
9
lanczos
10
雙三次樣條曲線
?vc <[-]編解碼器1,[-]編解碼器2,...[,]>
設置可用編解碼器的優先級列表, 按照它們在codecs.conf中的編解碼器名稱. 在名稱前加’-’表示忽略該編解碼器.
注意:
全部可用編解碼器的完整列表參見?vc help的輸出.
如果列表結尾有一個’,’ 將可以使用沒有列出的編解碼器作為后備.
示例:
?vc divx
指定使用Win32/VFW DivX編解碼器, 沒有后備
?vc divx4,
先嘗試divx4linux編解碼器, 然后使用后備
?vc -divxds,-divx,
嘗試除了Win32 DivX編解碼器之外的編解碼器
?vc ffmpeg12,mpeg12,
嘗試libavcodec的MPEG1/2編解碼器, 然后嘗試libmpeg2, 然后其它
?vf <...,濾鏡3[=選項],濾鏡2,濾鏡1>
激活一個反序排列的逗號分隔的視頻插件和它們的參數的列表.
注意:
參數是可選的, 當被省略時, 有些會設為默認值. 使用’-1’保持默認值. 參數w:h標識寬度x高度, 以點為單位, x:y表示相當圖像左上角x;y 的位置.
全部可用插件的完整列表參見?vf help的輸出.
可用插件有:
crop[=w:h:y]
切割圖像的指定部分其余丟棄. 用于去掉寬銀幕電影的黑邊.
w,h: 切割部分的寬和高, 默認值為原始的寬度和高度.
x,y: 切割部分的位置, 默認值是中央.
cropdetect[=0?255]
計算必要的切割參數并把推薦值顯示在標準輸出上. 極限值 的 設置可以從無(0)到所有(255).(默認值: 24)
rectangle[=w:h:y]
在圖像的指定坐標出繪制一個指定寬度和高度的矩形(用來實 驗crop的參數).
w,h: 寬度和高度(默認值: -1, 保證邊界仍然可見的最大可能 寬度).
x,y: 左上角坐標(默認值: -1, 最左最上)
這個插件會響應input.conf中的’change_rectangle’指令, 需 要兩個參數. 第一個參數可以是0表示w, 1表示h, 2表示x或者3 表示y. 第二個參數標識每次改變目標矩形邊界的點數.
expand[=w:h:y]
把電影的分辨率擴展(不縮放)到指定的值并把原始圖像放在坐標x, y處. 可以用獲得的黑帶顯示字幕/OSD.
w,h: 擴展后的寬度, 高度(默認值: 原始的寬度, 高度)
x,y: 擴展后的圖像中原始圖像的位置(默認值: 中央)
o: OSD/字幕渲染 0: 禁用(默認值) 1: 啟用
w和h的負參數視為相對原始尺寸的偏移, 例 如expand=0:-50:0:0在圖像底部增加50個像素的邊界.
flip
上下翻轉圖像. 參見?flip選項.
mirror
沿Y軸鏡像圖像.
rotate[=<0-7>]
+/? 90度的旋轉并翻轉(可選)圖像. 參數為4-7之間的旋轉只有 當電影的形狀是縱向而不是橫向時.
scale[=w:h[:c[:p]]]
使用軟件縮放(很慢)來縮放圖像并進行YUV<?>RGB色彩空間轉換( 參見?sws參數).
w,h: 縮放后的新寬度/高度(默認值: 原始的寬度, 高度) 注意: 如果使用了?zoom, 而后繼的濾鏡(包括libvo)不支持縮放, 那么它的默認值為d_width/d_height!-1: 原始的width/height 0: 縮放后的d_width/d_height-2: 用另外尺度和預放大的長寬比計算w/h. -3: 用另外尺度和原始的長寬比計算w/h.
c: 色度抽樣 0: 使用所有可用的輸入行的色度 1: 使用每2個輸入行的色度 2: 使用每4個輸入行的色度 3: 使用每8個輸入行的色度
p: 縮放參數(取決于所用的縮放模式) 對于-sws 2(二次立方)這表示銳化(0 (柔化) - 100 ( 銳 化)) 對于-sws 7(線性)這表示銳化(0(柔化) - 100(銳化)) 對于-sws 9(lanczos)這表示濾鏡長度(1 - 10) 0表示(按長寬比)縮放的目標w/h. (默認值: 原始w/h, 與?zoom同時 使 用表示目標w/h), 可選用色度采樣(c從0到3)和設置縮放參數. (細節參見?sws選項)
yuy2
指定使用YV12/I420或422P到YUY2的軟件轉換. 用于當顯卡/ 驅 動顯示YV12速度慢而YUY2速度快的情況.
yvu9
指定使用YVU9到YV12的軟件轉換. 不管軟件縮放的設置.
rgb2bgr[=swap]
RGB 24/32 <?> BGR 24/32色彩空間轉換.
swap: 同時進行R<?> B互換.
palette
使用調色板進行RGB/BGR 8 ?> 15/16/24/32bpp色彩空間轉換.
format[=fourcc]
限制下一個插件使用的色彩空間而不進行任何轉換. 與scale插件一起用于一次真實轉換.
fourcc: 類似rgb15,bgr24, yv12等等的格式(默認值: yuy2)
pp[=濾鏡1[:選項1[:選項2...]]/[-]濾鏡...]
這個選項開啟MPlayer的內部后期處理濾鏡的使用, 同時提供一個你可以向有名字的濾鏡傳送選項的接口. 可用濾鏡的列表 參 見?pphelp的輸出.
注意每一個子濾鏡都必須用一個/記號分隔.
所有濾鏡默認作用于’c’(色度).
在選項后面可以加上一個’:’和一個字母表示它的作用范圍:
a: 如果CPU太慢則自動關閉濾鏡.
c: 同時進行色度處理.
y: 不進行色度處理(只進行亮度處理).
示例:
?vf pp=hb/vb/dr/al/lb
?vf pp=hb/vb/dr/al
使用除了亮度/對比度修正之外的默認濾鏡:
?vf pp=de/?al
使用默認濾鏡和時間噪音消除:
?vf pp=de/tn:1:2:3
僅對亮度柔化馬賽克并根據CPU可用時間打開或關閉垂直柔化 馬賽克:
?vf pp=hb:y/vb:a ?autoq 6
test
產生各種設置樣式.
lavc[=quality:fps]
用于DVB/DXR3的通過libavcodec進行YV12到MPEG1的快速轉換. 比?vf=fame速度更快質量更好.
quality: 1 ? 31 固定qscale 32 ?固定比特率, 以kBits為單位
fps: 指定輸出幀速率(浮點數) (默認值: 0, 基于高度的自動檢測)
fame
用于DVB/DXR3的YV12到MPEG1的快速轉換.
dvbscale[=aspect]
使用DVB卡的最佳縮放, X軸以硬件縮放而Y軸用軟件縮放以保 持 長寬比.
aspect: 控制長寬比, 按DVB_HEIGHT*ASPECTRATIO計算(默認值: 576*4/3=768), 對 于16:9 的電視把它設置為576*(16/9)=1024.
只應該與expand+scale 一 起 使 用: ?vflavc,expand=-1:576:-1:-1:1,scale=-1:0,dvbscale
noise[=亮度[u][t|a][h][p]:色度[u][t|a][h][p]]
增加噪音.
<0?100>: 亮度噪音
<0?100>: 色度噪音
u: 均衡噪音 (否則使用高斯算法)
t: 時間噪音 (噪音樣式隨幀改變)
a: 平均隨機噪音 (更平滑, 有點慢)
h: 高質量 (看起來稍為好些, 有點慢)
p: 在一個(半)規則樣式中混入隨機噪音
denoise3d[=亮度:色度:時間]
這個濾鏡的目標是降低圖像噪音生成平滑圖像并讓靜止圖像真正靜止, (這有利于壓縮). 它可以加0到3個參數. 如果你省略一 個參數, 將猜測一個合理的值.
亮度:
空間亮度濃度 (默認值 = 4)
chroma:
空間色度濃度 (默認值 = 3)
time:
時間強度 (默認值 = 6)
hqdn3d[=luma:chroma:time]
高精度/質量的denoise3d濾鏡. 參數和使用方法相同.
eq[=亮度:對比度]
像硬件均衡器一樣可以交互控制的軟件均衡器, 用于不支持硬件 亮度對比度控制的顯卡/驅動. 也可以用于MEncoder, 修復捕捉質量差的電影, 或者略微降低對比度來掩蓋加工痕跡或獲得較低 的比特率. 初始值可以由命令行給出, 范圍在-100 ? 100之間.
eq2[=gamma:對比度:亮度:色相:rg:gg:bg]
另一個使用查表的軟件均衡器(非常慢), 在簡單的亮度, 對比度 和色相調整之外還支持gamma修正. 注意當所有gamma值都為1.0 時, 它使用與?vf eq一樣的MMX優化代碼. 參數以浮點值給 定. 參數rg, gg, bg 是紅, 綠, 蘭組份的獨立gamma值. 默認值 為1.0, 亮度=0.0. gamma的取值范圍是0.1?10,對比度是-2?2( 負數產生負片效果), 亮度是-1?1而色度為0?3.
halfpack[=f]
把 4:2:0的planar YUV轉換為4:2:2高度減半的packed格式, 降低 亮度采樣率但保持所有色度樣本. 用于輸出到硬件縮放質量 差或不可用的低分辨率顯示設備. 也可以作為一個cpu消耗很低的簡單的僅用于亮度的交錯/逐行掃描轉換器. 默認情況下, halfpack在降低采樣率的時候去兩行的平均值. 可選的參數f可 以是0表示只使用偶數行, 或者1表示只使用奇數行.
dint[=sense:level]
檢測并丟棄視頻流中的隔行掃描的幀. 參數取 值 范 圍 從0.0 到1.0 - 第一個(默認值 0.1)表示相鄰點的相對差別, 第二個( 默認值 0.15)表示檢測圖像的哪一部分來決定是否把幀作為隔行掃描丟棄.
lavcdeint
使用libavcodec的隔行/逐行掃描轉換濾鏡.
unsharp=l|cWxH:amount[:l|cWxH:amount]
反銳化掩飾/高斯模糊.
l: 應用到亮度組份.
c: 應用到色度組份.
WxH: 矩 陣的寬度和高度, 兩個方向都必須是奇數 (最小 = 3x3, 最大 = 13x11或者11x13, 一般在3x3到7x7之間)
amount: 加到圖像上的銳化/模糊的相對量 (正常范 圍 應 該 是-1.5 ? 1.5).<0: 模糊 >0: 銳化
swapuv
交換U & V平面.
il=[d|i][s][:[d|i][s]]
交錯/逐行轉換. 這個濾鏡的目標是分區處理交錯圖像而不進行逐行轉換. 你可以用它處理你的交錯圖像的DVD, 不必交錯圖像就可以在電視上播放它. 當逐行處理(用后期處理濾鏡)會永久 破壞交錯圖像(用平滑, 平均等等), 逐行處理會把幀分成兩塊( 成 為半圖像), 所以你需要分別進行(處理)他們然后把它們重新交錯.
d: 逐行
i: 隔行
s: 交換域(交換偶數&奇數行)
field[=n]
使用步進算法解壓交錯圖像中的單獨域從而避免浪費CPU 時 間. 可選參數n設置解壓偶數域還是奇數域(取決于n是偶數還是奇 數).
detc[=變量1=參數1:變量2=參數2:...]
嘗試反轉"telecine"過程生成一個電影幀速率的干凈的非交錯的 視頻流. 這個濾鏡還在試驗階段但似乎可用. 你必須明白如果你看電影的時候沒有交錯現象, 這個濾鏡絕對沒有用. 下面的參數(參考上面的語法)可以用來控制它的行為:
dr: 設置掉幀模式. 0(默認)表示不掉幀以保持固定的輸出幀 速率. 1表示總是如果前5幀沒有掉幀或telecine合并 就 掉1 幀. 2 表 示總是保持準確的5:4的輸入輸出幀比率. (注意: MEncoder使用1!)
am: 分析模式. 可用參數有0(使用fr=#設置的初始幀數的固定樣式), 和1(擴張性搜索telecine樣式).默認值為1.
fr: 設置初始幀數序列. 0-2是三個干凈的漸進幀; 3和4是兩個交錯幀. 默認值, -1, 表示"不在telecine序列中". 這 里 設置的數字是假想的電影開始前的幀數.
tr0, tr1, tr2, tr3: 特定模式的初始值.
telecine[=開始]
使用3:2的"telecine"過程增加幀速率20%. mplayer的這個功能 應該不能正常工作, 不過它可以 用 于’mencoder-fps 29.97 -ofps 29.97 -vf telecine’. 兩個fps選項都是必需的! (如 果錯誤將導致A/V不同步). 可選的開始參數告訴濾鏡telecine格式從哪里開始(0-3).
tfields[=模式]
臨時域分離 -- 把域分成幀, 輸出幀速率加倍. 0模式時, 濾鏡保持域不變, 輸出結果高度減半. 1模式時, 圖像的交錯部分將 被 改 寫 重 新 構 成 完 整高度的幀. 跟telecine濾鏡一樣,"tfields"只有用mencoder, 并且只有-fps和-ofps都設置成需要的(加倍)的幀速率時才能正常工作!
boxblur=半徑:強度[:半徑:強度]
盒子模糊
半徑: 濾鏡大小
強度: 濾鏡應用的強度
sab=半徑:強度:色差[:半徑:強度:色差]
外形識別模糊
半徑: 模糊濾鏡強度(~0.1?4.0)(越大越慢)
強度: 預過濾強度(~0.1?2.0)
色差: 可以容忍的像素差別.(~0.1-100.0)
smartblur=半徑:強度:閥值[:半徑:強度:閥值]
只能模糊
半徑: 模糊濾鏡強度(~0.1?5.0)(越大越慢)
強度: 模糊(0.0?1.0)或銳化(-1.0?0.0)
閥值: 過濾全部(0), 過濾單調區域(0?30)或過濾邊界(-30?0)
perspective=x0:y0:x1:y1:x2:y2:x3:y3:t
形狀修正
x0,y0,...: 左上, 右上, 左下, 右下坐標
t: 線性(0)或立方(1)重新采樣
2xsai
使用雙倍放大插入算符放大并平滑圖像.
1bpp
1bpp位圖到YUV/BGR8/15/16/32轉換
down3dright[=行數]
重新配置縮放立體圖像. 解壓兩個立體域并把它們放在 一起, 重新縮放以維持原始電影長寬比.
行數: 從圖像中部選擇的行數(默認值: 12)
bmovl=隱藏:不透明:<命名管道>
從一個命名管道讀取位圖并把它們顯示在窗口中.
隱藏: 設置’隱藏’標記的默認值(布爾值)
不透明: 切換alphablended(透明)和不透明(快速)模式標記
命名管道: 命名管道的路徑/文件名(連接mplayer -vf bmovl 和控制程序的命名管道)
命名管道命令有:
RGBA32 width height xpos ypos alpha clear
接受width*height*4字節的原始RGBA32數據
ABGR32 width height xpos ypos alpha clear
接受width*height*4字節的原始ABGR32data.
RGB24 width height xpos ypos alpha clear
接受width*height*3字節的原始RGB32data.
BGR24 width height xpos ypos alpha clear
接受width*height*3字節的原始BGR32data.
ALPHA width height xpos ypos alpha
改變區域的alpha值
CLEAR width height xpos ypos
清除數據
OPAQUE
禁用所有alpha透明發送"ALPHA 0 0 00 0"可以重新打開 它.
HIDE
隱藏位圖
SHOW
顯示位圖
參數有:
width, height: 圖像/區域尺寸
xpos, ypos: 位圖傳送的X/Y位置
alpha: 設置alpha差別. 0標識原始值, 255使所有都不透明, -255使所有都透明. 如果你把它設為-255, 你可以隨后發 送 一 個ALPHA命令序列吧區域設置為-225, -200, -175等等來獲 得一個漂亮的淡入效果!
clear: 傳送前清楚幀緩沖. 1表示清除, 如果是0, 圖像會被傳送到老圖像上, 所以你不需要每次為屏幕小部分的變化都發 送1,8MB的RGBA32數據.
?vfm <驅動1,驅動2,...>
設置可用的視頻驅動優先級列表, 按照它們在codecs.conf中的驅動名稱. 當都不可用是使用默認后備驅動.
注意:
如果編譯了libdivxdecore支持,則odivx和divx4會包含同一個DivX4編解 碼器, 但用不同的API調用它. 他們的區別和什么情況下應該使用哪一個, 參考文檔的DivX4部分.
全部可用編解碼器的完整列表參見?vfm help的輸出.
示例:
?vfm ffmpeg,dshow,vfw
先嘗試libavcodec, 然后是Directshow,然后是VFW, 如果都不 行就使用其它后備編解碼器.
?vfm xanim
先嘗試XAnim編解碼器
?x <x> (僅用于MPLAYER)
把圖像縮放到寬度x(如果軟件/硬件縮放可用). 禁用長寬比計算.
?xvidopts <選項1:選項2:...>
設置使用XviD解碼時的附加參數.
dr2
激活直接渲染模式2.
nodr2
關閉直接渲染模式2.
?xy <x>
x<=8
按因子<x>縮放圖像.
x>8
把圖像寬度設為<x>并計算圖像高度以保持長寬比.
?y <y> (僅用于MPLAYER)
把圖像縮放到高度y(如果軟件/硬件縮放可用). 禁用長寬比 計 算..TP ?zoom 在可能的情況下使用軟件縮放. 可以用來指定?vf scale進行縮放.
注意:
如果沒有?zoom選項?vf scale將忽略?x / ?y / ?xy / ?fs / ?aspect等 選項.
編碼選項 ( 僅用于 MENCODER)
?audio-density <1?50>
每秒的音頻塊數(默認是兩個0.5秒的長音頻塊).
注意:
僅用于CBR, VBR將忽略它因為它把每個包放在一個新塊中.
?audio-delay <0.0?...>
設置文件頭中的音頻延遲域. 默認值為0.0, 負數不能正常工作. 這不 是在編碼的時候延遲音頻, 而是播放器會把它作為默認的音頻延遲, 你 可以不必用?delay選項.
?audio-preload <0.0?2.0>
設置音頻緩沖間隔(默認值: 0.5秒).
?divx4opts <選項1:選項2:...>
當用DivX4編碼時, 你可以由此設置參數.
可用選項有:
help
獲得幫助
br=<參數>
設置比特率以
kbit<4?16000>或者
bit<16001?24000000>為單位
key=<參數>
最大關鍵幀間隔(以幀為單位)
deinterlace
啟用逐行掃描(別用它, DivX4很buggy)
q=<1?5>
質量(1?最快, 5?最好)
min_quant=<1?31>
最小量化值
max_quant=<1?31>
最大量化值
rc_period=<參數>
速率控制周期
rc_reaction_period=<參數>
速率控制反應周期
rc_reaction_ratio=<參數>
速率控制反應率
crispness=<0?100>
設置生硬/平滑
pass=<1?2>
用這個選項你可以編碼2 pass的DivX4文件. 先用pass=1編碼, 然后以同樣的參數, 用pass=2編碼.
vbrpass=<0?2>
代替pass參數并使用XviD VBR代替DivX4 VBR. 可用選.
?
?
使用GPU加速H.264編碼分析
繼前面的“GPGPU”和“CUDA和OpenCL”的簡介后,接下來分析一個具體的使用案例:是否可以用GPU搭建一個高性能的H.264編解碼服務器?
設想一個簡單的需求:
- 把其他編碼的視頻轉換為指定碼率的H.264;
- 在轉換過程中做一些簡單的處理(例如增刪水印、字幕的處理、聲音的處理等);
- 需要封裝成指定的一種container格式,比如mp4或mkv。
?
ffmpeg完成此項工作的大概過程是:
- 識別文件格式,打開視頻文件容器,得到video_stream;
- 使用libavcodec把video_stream解碼成原始的frame數據;
- 在frame的基礎上做“需求2”的處理;
- 編碼成H.264格式;
- 存放到指定格式的容器中(mp4或者mkv)。
“過程1”應該是一個輕量操作,且對于現有視頻格式速度應該很快(播放器看片的時候不可能先等上幾秒分析一把格式再開始播放吧?)。
“過程2”需要把原有的視頻編碼解碼并轉為ffmpeg內部使用的格式,速度會比上第一步慢不少,但是應該也是可以接受的。當然在碼率比較高的情況下也會非常緩慢(在Pentium4時代的機器上看1080p的高清視頻很卡)。
“過程3”是需要對每一幀進行處理,那么這步是可高度并行化的應該可以放到GPU進行。
“過程4”一定是最慢的一個環節:H.264需要將圖像分割成很多個宏塊, 然后利用視頻幀圖像的幀內和幀間的相關性, 采用幀內預測或幀間預測的編碼模式, 對各個宏塊進行壓縮。然后形成幀,組成為碼流。整個過程復雜,但宏塊兒的處理是可以高度并行化的操作,應該可以放到GPU進行。
“過程5”和“過程1”類似。
所以如果想用GPU加速以上的過程,那么把“過程4”和“過程2”的密集計算從CPU上轉到GPU上,應該是可能的發力點。
如果要設計這個系統,軟件自底層到上層有幾點需要考慮:
- 如果顯卡可以指定,應該是Nvidia。在Linux下有完善的開發運行環境,且同時支持CUDA和OpenCL;
- 如果選定Nvidia顯卡,那么根據前文的分析,使用CUDA是更好的GPU計算架構。并且應該使用最新的CUDA 4.0版本,因為在多GPU上能更方便的開發,并且GPU直接訪問內存方面也做出了改進(CUDA 4.0的新特性詳細見這里)。
- 在決定了以上基礎設施后,為了提高單機的處理能力程序應該用何種架構來編寫?單進程多線程還是多進程單線程?
關鍵在于在程序里如何更好的調用CUDA:
- 單進程多線程方式
- 每個線程進行一個視頻的轉換,每個線程在其線程內部直接使用CUDA;
- 有單獨的CUDA線程,其他線程當需要時通知此線程進行運算;
- 多進程單線程
- 每個進程進行一個視頻的轉換,在其進程內部各自獨立的使用CUDA;
- 有單獨的GPU進程,其他進程當需要進行GPU運算的時IPC通知此進程進行;
在我看來,2-1的方式是最簡單直接的,可以直接基于ffmpeg來實現,只需單把可并行化的部分從CPU移到GPU。但是CUDA 4.0是否支持這樣做?這樣做效率是否最高?
硬件配置上也有以下的問題:
- 是否需要在一個Server上配置多塊兒GPU?雖說CUDA 4.0已經聲稱對此有很好的支持,但是其是否能利用好?另外受限于硬件瓶頸的一些限制(CPU計算能力、內存速度、總線速度),配置幾塊兒GPU比較合適?
- 如果使用ffmpeg,那么在一臺擁有16核的服務器上,理論可以同時啟動16個ffmpeg進程(單線程運行)。加入GPU運算后單個視頻處理速度的提高是一定的,但是否還有這么大的并行能力?以及單位時間段內的處理能力是否提升?
- 加入GPU后硬件成本的增加是否值得?與單獨使用CPU的相比單位成本是否更低?選用哪款Nvidia顯卡的性價比最高?
- 如何看GPU的load average和top?
最后這件事情最難的一點在于:需要對CUDA、ffmpeg、H.264、硬件都有相當深入的了解才能做好這樣的一個系統。
分析H.264在ADSP-BF561上的實現及優化
隨著互聯網在全球范圍逐漸普及,移動通信飛速發展,網絡傳輸以及各種各樣的多媒體業務的出現,對視頻編解碼技術更是提出了許多新的要求。如何提供更加優秀的視頻傳輸成為信息科學與技術的研究熱點。
H.264/AVC是由國際電信聯"A盟(ITU—rn的視頻編碼專家組ⅣCEG)與國際標準化組織(ISO/IEC)的運動圖像專家組(MPEG)聯合提出的最新一代的視頻編碼標準。是目前圖像通信研究領域的熱點技術之一。其主要思想仍是采用基于塊的混合編碼方法,在同等壓縮質量情況下,編碼效率大約為MPEG-4標準的二倍。它提供了移動環境中包丟失和比特誤碼的恢復工具,視頻編碼層和網絡適配層的分層結構提高了網絡友好性。但是 H.264運算復雜度很高,在實時視頻編解碼實現中面臨著巨大的挑戰。ADSP—BF561是ADI公司推出的高性能多媒體處理器,它具有兩個處理核心,最高時鐘頻率達到600MHz,其內部采用哈佛總線結構,存儲模型層次化,可以滿足實時編解碼算法的需求。本文提出了一套采用ADSP-BF561芯片實現H.264視頻壓縮算法的設計方案,結合該DSP平臺對算法進行了針對性的優化,充分發揮了ADSP-BF561強大的處理能力。
1 算法介紹
1.1 H.264編碼模型框架
H.264以其高壓縮比、高圖像質量和良好的網絡親和性廣受業界歡迎。在同等質量條件下,H.264的數據壓縮比比MPEG-2高2~3倍,比MPEG-4高1.5~2倍。其需要的帶寬只有MPEG-4的50%, MPEG-2的12.5%。
H.264標準采用分層體系結構,系統分為:視頻編碼層VCL(VideoCoding Layer),負責高效的數字視頻壓縮;網絡抽象層NAL(Network Abstraction Layer),負責對數據進行打包和傳送。H.264編碼圖像通常分為三種類型:I幀、P幀、B幀。I幀為幀內編碼幀,其編碼不依賴于已編碼的圖像數據。 P幀為前向預測幀,B幀為雙向預測幀,編碼時都需要根據參考幀進行運動估計。同時,H.264在提高圖像傳輸容錯性方面做了大量工作,重新定義了適于圖像的結構劃分。在編碼時,圖像幀各部分被劃分到多個Slice結構中,每個Slice都可以被獨立編碼,不受其他部分影響。Slice由圖像最基本的結構 ——宏塊組成,每個宏塊包含一個16×16的亮度塊和兩個8×8的色度塊。H.264標準的整體編碼框圖如圖1所示。編碼過程中,原始數據進入編碼器后, 當采用幀內編碼時,首先選擇相應的幀內預測模式進行幀內預測,隨后對實際值和預測值之間的差值進行變換、量化和嫡編碼,同時編碼后的碼流經過反量化和反變換之后重構預測殘差圖像,再與預測值相加得出重構幀,得出的結果經過去塊濾波器平滑后送入幀存儲器。采用幀間編碼時,輸入的圖像塊首先在參考幀中進行運動估計,得到運動矢量。運動估計后的殘差圖像經整數變換、量化和嫡編碼后與運動矢量一起送入信道傳輸。同時另一路碼流以相同的方式重構后,經去塊濾波后送入幀存儲器作為下一幀編碼的參考圖像。
1.2H.264關鍵技術
1.2.1 幀內預測
H.264引入了幀內預測以提高壓縮效率。幀內預測編碼就是利用周圍鄰近的像素值來預測當前的像素值,然后對預測誤差進行編碼。這種預測是基于塊的。對于亮度分量,塊的大小可以在16×16和4×4之間選擇,16×16有4種預測模式,4×4有9種預測模式;對于色度分量,預測是對整個8×8塊 進行的,有4種預測模式。
1.2.2幀間預測
幀間預測時所用塊的大小可變。假設基于塊的運動模型,其塊內的所有像素都做了相同的平移,在運動比較劇烈或者運動物體的邊緣外,這一假設會與實 際出入較大,從而導致較大的預測誤差,這時減小塊的大小可以使假設在小塊中依然成立。另外小塊所造成的塊效應相對也小,因此,小塊可以提高預測的效果。 H.264一共采用了7種方式對一個宏塊進行分割,每種方式下塊的大小和形狀都不相同,編碼器可以根據圖像的內容選擇最好的預測模式。與僅使用16x16 塊進行預測相比,使用不同大小和形狀的塊可以使碼率節約15%以上。
同時,幀內預測采用了更精細的預測精度,H.264中亮度分量的運動矢量使用1/4像素精度。色度分量的運動矢量使用1/8像素精度。
1.2.3多幀參考
H.264支持多幀參考預測,最多可以有5個在當前幀之前的解碼幀作為參考幀產生對當前幀的預測,提高H.264解碼器的錯誤恢復能力。
1.2.4整數變換
H.264對殘差圖像的4×4整數變換技術,采用定點運算來代替以往DCT變換中的浮點運算。以降低編碼時間,同時也更適合硬件平臺的移植。
1.2.5熵編碼
H.264支持兩種熵編碼方法,即CAVLC(基于上下文的自適應可變長編碼)和CABAC(基于上下文的自適應算術編碼)。其中CAVLC的抗差錯能力比較高,但編碼效率比CABAC低;而CABAC的編碼效率強,但需要的計算量和存儲容量更大。
1.2.6去方塊濾波
去方塊濾波的作用是消除經反量化和反變換后重建圖像中由于預測誤差產生的塊效應,從而改善圖像的主觀質量和預測誤差。經過濾波后的圖像將根據需 要放在緩存中用于幀間預測,而不是僅僅用來改善主觀質量,因此該濾波器位于解碼環中。對于幀內預測,使用的是未經過濾波的重建圖像。
2 算法實現
2.1 平臺選擇
2.1.1 ADSP-BF561芯片介紹
ADSP-BF561是Blackfin系列中的一款高性能定點DSP視頻處理芯片。其主頻最高可達750 MHz,內核包含2個16位乘法器MAC、2個40位累加器ALU、4個8位視頻ALU,以及1個40位移位器。該芯片中的兩套數據地址產生器(DAG) 可為同時從存儲器存取雙操作數提供地址,每秒可處理1 200兆次乘加運算。芯片帶有專用的視頻信號處理指令以及100KB的片內L1存儲器(16 KB的指令Cache,16 KB的指令SRAM,64 KB的數據Cache/SRAM,4KB的臨時數據SRAM)、128 KB的片內L2存儲器SRAM,同時具有動態電源管理功能。此外,Blackfin處理器還包括豐富的外設接口,包括EBIU接口(4個128 MB SDRAM接口,4個1 MB異步存儲器接口)、3個定時/計數器、1個UART、1個SPI接口、2個同步串行接口和1路并行外設接口(支持ITU-656數據格式)等。Blackfin處理器在結構上充分體現了對媒體應用(特別是視頻應用)算法的支持。
2.1.2 ADSP-561 EZkite
ADSP-BF561視頻編碼器平臺采用ADI公司的ADSP-BF561 EZ-kit Lite評估板。此評估板包括1塊ADSP-BF561處理器、32MB SDRAM和4 MBFlash,板中的AD-V1836音頻編解碼器可外接4輸入/6輸出音頻接口;而ADV7183視頻解碼器和ADV7171視頻編碼器則可外接3輸入/3輸出視頻接口。此外,該評估板還包括1個UART接口、1個USB調試接口和1個JTAG調試接口。攝像頭輸入的模擬視頻信號經視頻芯片ADV7183A轉化為數字信號,此信號從ADSP-BF561的PPI1(并行外部接口)進入ADSP-BF561芯片進行壓縮,壓縮后的碼流則經ADV7179轉換后從ADSP-BF561的PPI2口輸出。此系統可通過FLASH加載程序,并支持串口及網絡傳輸。編碼過程中的原始圖像、參考幀等數據可存儲在SDRAM中。
2.2 算法選取與優化方案
2.2.1 算法選取
H.264實現的源代碼不止一種,其中最常見的有JM、X264和T264。對比這三種實現源代碼,X264比T264具有更高的效率。而且相比廣泛采用的JM編碼模型,X264在兼顧編碼質量的同時大幅度地提升了編碼速度,所以選取X264作為算法原型。
2.2.2 優化方案
該優化方案從三個層次對算法進行優化:算法層次、代碼層次、平臺層次。下面介紹具體優化方法。
2.2.2.1編碼器具體參數的選擇
該編碼器使用main檔次,I、B、P幀量化值分別為26、31、29,流控參數選為CBR。IDR幀間隔設為50,B幀間隔為2幀。這樣的選擇是為了在速度和運算量上取折中。選用B幀并將其量化值加大,可比baseline檔次、IPPP結構提高約10%的壓縮率。而B幀的計算量,因其不用做參考幀,故無需進行去塊濾波和插值計算,在31的qp下,很多塊會被判做skip模式編碼,因而多數時B幀總運算量候反而較P幀低。
2.2.2.2 算法層次的優化
算法層次的優化主要是指在參數選定的情況下,對部分算法所作的替換或優化。和參數的選擇一樣,算法層次優化也主要受優化策略的指導。如運動匹配 準則是選用SSD、SAD或SATD。如果只看中準確程度,則選擇SSD最佳;如果只看中運行速度,則選擇SAD最佳;如果要兼顧二者,則選用SATD是 比較好的一個方案。在進行算法優化時還應該注意一個問題,即要考慮實際運行平臺的支持情況。如在追求速度的策略下,匹配準則選用SAD,如果只計算一半的 點則會大大降低運算速度。但是如果考慮ADSP-BF561匯編指令的設計情況,就會發現這樣做反而會增加指令數,會使速度更低。算法層次優化包括如下幾個部分:
(1)除法求余。改進策略是浮點型算法盡量改為整型,64位盡量改為32位,32位盡量改為16位。而對于某些計算比較多的,則改為查表計算。在ADSP-BF561平臺上,一次32位整形除法需耗時300個CYCLE,而查表僅需幾個CYCLE,這樣的改進能顯著提高速度。
(2)飽和函數。在視頻的計算中,幾乎每次像素的計算都會調用飽和函數,X264代碼的實現中已將這部分代碼改為查表函數,在其他的編解碼器實 現中也有將這部分改為一個判斷和幾個邏輯運算的形式。對大部分DSP平臺,采用判斷跳轉會打斷流水線,即使平臺有比較好的跳轉預測功能,打斷流水仍然會造 成stall。所以查表方法是一種高效方法。而在ADSP-BF561匯編指令中,可以通過設置指令后綴或使用某些特殊指令來進行飽和工作。甚至不用查表,在不同的場合使用不同的飽和算法能大大提高代碼的執行效率。
(3)MC部分函數。實測中發現MC部分函數運行效率不如ffmpeg解碼器中MC部分效率高,所以將這部分代碼用ffmpeg中的相應部分替換。此外qpel16_hv函數中計算有冗余,減少這些冗余能提高代碼運行效率。
(4)算法替代和改進。幀間預測的改進:關于算法的改進主要集中在對me(motion estimation)的改進上,流程如圖2所示。 costmin1=min(cost16,cost8,cost16×8,cost8×16),costmin2=min(costmin1,costsub), 依次在16×16、8×8、16×8和8×16大小宏塊的整像素位置做預測,再做次像素估計和幀內預測,選用匹配準則函數(采用sad作為匹配準則函數) 取得最小值的模式進行編碼。每計算一種模式,都將sad值與一個經驗閥值做比較。當sad值小于這個閥值時,立即結束運動估計,從而減少運算量。
幀內預測的改進:H.264標準所采用的幀內預測模式除了DC模式都具有方向性,相鄰4×4塊都具有相關性。根據這樣的相關性,只將當前4×4 塊上邊和左邊選用預測模式及其相鄰的兩種預測模式作為當前4×4塊的預測模式,當其閥值都大于一個經驗閥值時,才采用DC模式。這樣的方案不用一一計算9 種預測模式,在復雜度、編碼效率、質量和速度上取了一個折中。流程如圖3所示。
2.2.2.3代碼層次優化
針對ADSP-BF561平臺,代碼層次的優化工作包括以下幾個方面:
(1)內聯函數。將經常調用的函數體較小的函數改為內聯。編譯條件中有關于內聯函數優化的選項。內聯函數的使用是將代碼的大小和運行效率取一個折中。根據實際情況,代碼的大小并非限制條件,所以應盡可能多地使用內聯函數。在項目配置中選中when declaredinline選項。
(2)跳轉預測。ADSP-BF561采用了靜態預測的方式來預測有條件判斷情況,預測不成功會造成4~8個內核時鐘(CCLK)的延誤。如果事先知道某些跳轉的概率,將可能性最大的分支放在最前面,可以從概率上降低預測不成功而造成的stall。
(3)使用硬件支持循環。對于大部分平臺,將一些循環體小的循環展開也能提高效率。ADSP-BF561有兩組硬件計數器用以支持循環。所以除非是展開三層以上的循環,否則,展開循環體不能提高效率。
(4)內存。嵌入式系統的內存是非常寶貴的資源。避免頻繁的動態申請和釋放內存,能減少碎片產生,提高內存的利用率。X264工程也不會頻繁地申請釋放內存。在項目中,具體做法是編寫平臺相關的malloc和free函數。將經常使用的中間數據在L1數據空間中分配。
(5)注釋不需要代碼。去掉代碼中不需要的部分,主要會去掉CAVLC以及部分碼率控制、csp、cpu、信息統計、調試和psnr計算等部分代碼,這樣做的目的是為了減小文件大小和去除代碼中的一些跳轉。不建議刪除代碼,可以使用注釋符或用宏切換的方式,以防止以后參數改變時需要使用未使用過 的代碼。
2.2.2.4平臺層次優化
ADSP-BF561相應的編程參考和硬件參考對其平臺特性有詳細介紹。一些平臺自帶的優化功能,如CACHE的開啟和配置等不專門在此討論。
(1)匯編代碼編寫
使用匯編優化有兩個方法:對于LEAF函數(函數體中不再調用其余函數),采用整個函數完全用匯編指令重寫的方式;而對于NONLEAF函數則 可使用asm關鍵字,在C代碼中嵌入匯編代碼。在匯編代碼的編寫過程中一些情況會造成流水線stall,在編寫匯編代碼時要特別注意避免這些情況。IDE 集成了PIPLELINE VIEWER工具,如圖4所示。在編寫完成匯編代碼后,可使用該工具觀察運行時流水線的情況。如果有stall等出現,會給出原因,優化人員根據工具分析結果重新更改代碼,提高執行效率。
ADI公司提供的IDE具有非常靈活的設置,能根據用戶的需要生成針對不同限制的代碼。如內存有限,用戶可以設置生成文件更小的代碼;如果用戶更注重運行速度,則設置編譯器生成運行速度更快的代碼,或是在其間取一個折中。
ADSP-BF561有專門用于處理視頻相關的一些專用DSP指令(videopixel operations、vector operations等),這些專用指令通過SIMD技術或者操作專門硬件支持某些特殊運算(累加、多參數取均值,同時完成加減法等),以提高運行速度。 如前文求SAD情況,匯編指令中有指令專門計算連續4個像素與另外連續4個像素之差的絕對值之和,結果與累加器的值相加。如果要隔點算(即取一半的點計 算),反而需要增加指令后對數據進行下采樣,既耗時而且不準確。所以采用計算一半像素點的策略并不適用于ADSP-BF561。編譯器自動生成的代碼中不 會使用到這些專用指令。所以只能根據對算法的理解和對平臺的熟悉程度來對算法進行匯編優化。
在編寫匯編代碼時還需注意部分寄存器的使用,如I0、I1,其值不僅用做地址索引,還會影響許多指令的計算結果。在使用這些寄存器時,一定要注意將其壓棧或置為適當的值。此外,關于數據的載入,一般應遵循對齊原則,但在做運動估計計算匹配準則函數時,這樣的要求往往達不到。故如能將兩者分開來計 算,將更能提高效率。
此外,應盡量合理地使用寄存器,多使用并行指令也能提高代碼的執行效率。
(2)分級存儲器結構
ADSP-BF561處理器采用改進的哈佛結構和分級的存儲器結構。Level1(L1)存儲器以全速運行,只有很少的延遲。在L1級,指令存儲器存放指令。兩個數據存儲器存放數據,一個專用的臨時數據存儲器存放堆棧和局部變量信息。由多個L1 存儲器組成的模塊,可進行SRAM和CACHE 的混合配置。存儲器管理單元(MMU)提供存儲器保護功能,對運行于內核上的獨立任務,可保護系統寄存器免于意外的存取。L1 存儲器是ADSP-BF561處理器內核中性能最高、最重要的存儲器。通過外部總線接口單元(EBIU),片外存儲器可以由SDRAM、FLASH和SRAM 進行擴展,可以訪問多達132 MB的物理存儲器。根據這樣的特點,將執行率更高的代碼放入L1指令緩存中,能使代碼更快地運行。IDE提供了Profile工具,能在運行時統計各個函 數所占的CYCLE數和占總CYCLE數的百分比。通過將X264中比較耗時的部分算法代碼,如模式選擇部分代碼放入L1指令空間,能進一步提升運行效 率。Profile工具統計結果同樣也是選擇需要使用匯編優化函數的依據,IDE可根據Profile結果對代碼進行優化。X264代碼Profile統 計結果與測試數據有很大關系,選用更類似以后應用場所的數據作為測試數據,能使統計結果更接近以后的應用環境。為達到比較準確的統計結果,最好在 Simulation階段進行統計。雖然這樣非常耗時,但為得到一個準確的統計作為參考依據是值得的。此外CACHE VIEWER工具能提供運行時CACHE的使用情況,使用它來分析CACHE的使用,對于提高代碼運行效率很有用處。
3 實驗結果評估
3.1 關鍵函數優化測試結果
采用以上優化方法對編碼關鍵函數進行優化,優化前后函數耗時如表1所示。可見,以上優化方法能大幅度減少編碼時間。
3.2測試序列測試結果
對三種測試序列在總線頻率120MHz下進行優化前后幀率測試,結果如表2所示。從表2可以看出,采用以上優化方法能顯著提高幀率。
3.3不同數據總線頻率下測試結果
對于不同的總線頻率,優化后編碼幀率不同,結果如表3所示,采用的測試序列為foreman。
本文介紹了H.264標準的框架,研究了X264軟件的實現方案,對ADSP-BF561處理器體系結構進行分析,提出了一套X264優化方 案,包括:算法替代和改進、內聯函數、匯編代碼編寫、高速存儲器應用等。測試結果表明,優化后的算法編碼效率有顯著提高,具有很強的實用價值。但是,本文主要從編碼速度和效率兩方面對編碼器進行優化,在復雜度和編碼質量上仍需不斷對關鍵算法進行分析整合,提出新的優化算法。同時,編碼器的碼率控制尚未完 善,如何在降低計算復雜度的前提下有效進行碼率控制,需進一步研究。
x264 耗時分析范例
測試環境:Intel Pentium4 3.00GHz (雙核cpu),開啟超線程
內存: DDR 1.00G
操作系統: Windows sever 2003 Enterprise Edition
分析軟件: Intel(R) VTune(TM) Performance Analyzer 8.0(評估版lic)
編譯軟件: VC71+nasm0.98
Bus Speed: 800MHz
測試程序: X264 20060506 編碼器
1. Debug版本
編碼參數:
X264 -fps -o foreman.264 forman.cif 352x288
編碼400frames,編碼效率:23fps左右(libx264 debug版本),35fps(libx264 release版本),提高了10fps以上,比較可觀
2. 編碼參數:
X264 -fps --no-asm -o foreman.264 forman.cif 352x288-no-asm,Disable all CPU optimizations即未使用mmx,mmxext,sse,sse2,3dNow,3dnow ext,altivec等匯編指令優化。
編碼400frames,編碼效率2.67fps(libx264debug版本),12.67fps(libx264 release版本),提高了10fps
Clockticks per Instructions Retired (CPI)表示該程序段的平均執行一條指令所需的時鐘周期數,CPI越大表示該程序段調用的浮點數操作,乘法,除法,I/O處理,系統調用或文件訪問等代價昂貴的操作較多。
Instructions Retired events, 表示執行的指令數,越大表示該模塊調用的較多。
Clockticks events 則表示該模塊所消耗的時鐘周期數,一般Clockticks events = Instructions Retired events * Clockticks perInstructions Retired (CPI),越大表示該模塊消耗的時間越多,后面的Clockticks %則表示該模塊的在所有程序中的時耗百分比。
這里有一點需要注意:(還是舉例吧),例如要分析視頻編碼中去塊濾波器算法/程序的時耗,并不是一個x264_frame_deblocking_filter函數的時間消耗就是所有x264編解碼過程中的時間消耗,由于 x264_frame_deblocking_filter調用deblck_edge,x264_clip3(該函數也被其他函數所調用)函數,而 deblock_edge下又調用x264_deblock_v8_luma_mmxext,x264_deblock_h_luma_mmxext,x_264_deblock_h_chroma_mmxext, deblock_luma_intra_c,x264_deblock_v_chroma_mmxext(這些函數通過指針重定義的方式以適應于不同的硬件平臺,比如Intel,AMD的CPU采用 不同的指令系統,其實Mplayer,FFMPEG,T264等軟件都采用類似的重定義方式,已達到一個軟件使用與不同構架/平臺,如 arm,powerpc,x86等)等函數。那么這里如果統計去塊濾波器的算法的時間消耗百分比,就需要將該函數及其所有調用的子函數的時間消耗都計算在內,x264_deblock_****都是唯一被deblock_edge調用,但對于x264_clip3,并不僅僅是去塊濾波器部分調用,那么就只 能部分計算在去塊濾波器之內,至于部分是多少要根據個函數的調用次數,這里不確定。
相關x264時耗分析數據后面的表格。deblock占4.3%左右,quant+dequant占3.3%左右,DCT+IDCT占1.1%左右,主要是運動估計和運動補償,ME中大量的sad/satd的計算,MC中的六階濾波器tap_filter是主要時耗,具體我沒有太細統計將近20% 左右,x264中由于采用了算法優化,程序優化及mmx,sse,sse2等指令優化,將原本消耗較大的去塊濾波器等都有了較大程度地優化。
這里再討論一下程序性能優化技術,程序性能優化可以大致從3個部分考慮。
1. 算法結構優化,實現同樣的應用功能可采用多種不同的算法和方 法,比如H.264種的運動估計全搜索和快速運動估計算法,實現的編碼效率基本一致,但是處理時間可以節省10~20倍,所以需要選擇高效的算法。還有遞 歸算法非遞歸化,遞歸算法使得程序結構清晰,可讀性高,但卻需要執行大量的過程調用,堆棧保存等,運行效率低下。
2. 編譯優化,現在很多編譯器都實現了較強的代碼優化功能,多數編譯器都基于數據流分析以實現別名分析(通過變量重命名來消除數據相關,提高流水線的執行效率),常數折疊,公共子表達式消除、冗余代碼刪除,循環逆轉和循環展開等與體系結構無關的優化,例如GNU gcc就是個很好的編譯工具。還有借用并行程序設計技術,進行相關性分析,并通過相應技術是程序具有更好的局部性以提高Cashe命中率。對于GCC中采 用-O-O2 -O3 -O4等選項選擇針對速度/面積等性能優化,另外debug版本由于程序中加入較多的debug參數,影響程序效率,上面x264的debug和 release運行效率的對比可見一斑.編譯優化屬于靜態優化,由編譯器自動完成,但是編譯器很難得到程序的語義信息,算法流程等信息。所以需要我們手工 編程優化以最大程度提高程序運行效率
3. 程序優化,包括a)使用inline函數,很多編譯器支持inline關鍵字,減少函數調用開銷卻增加了代碼量。b)針對程序運行平臺,如 x86(Intel),Xscale,ARM,DSP等不同構架,可采用相應的匯編優化,將主要時耗部分/循環調用等,進行匯編指令優化 MMX,SSE,WiMMX,ARM/Thumb指令,DSP匯編等,或者采用專用的庫函數,如針對Intel CPU/Xscale構架的嵌入式系統(PXA255,PXA270等)可使用IPP/GPP庫,提高程序效率。c)對于DSP系統,由于有多個并行處理單元,編譯器會并行優化,所以需要盡量減少頻繁小循環跳轉,將循環展開,同時減少循環或內層循環也可以提高CPU的流線效率,盡量不斷流。d)在 Switch語句中根據發生頻率排序case語句,編譯器對于switch語句將生成if-else-if的嵌套代碼,按概率排序可提高效率 (FPGA/CPLD等邏輯器件中,采用VHDL語言描述的switch是生成多個邏輯器件,并且完全并行的)。e)減少函數調用參數. f)減少耗時的浮點數操作,除法操作等降低CPI。
X264使用介紹
x264是一個開源的H.264視頻編碼函數庫。是最好的有損視頻編碼器。
主頁: http://www.videolan.org/developers/x264.html
x264.nl當前版本信息:x264 x86 8bit-depthr2145, x64 8bit-depth r2145. Checked 2012-01-16 10:00 GMT
目錄[隱藏]
|
H.264和x264
H.264是ITU(International Telecommunication Unite 國際通信聯盟)和MPEG(MotionPicture Experts Group 運動圖像專家組)聯合制定的視頻編碼標準。從1999年開始,到2003年形成草案,最后在2007年定稿有待核實。在ITU的標準里稱為H.264,在MPEG的標準里是MPEG-4的一個組成部分--MPEG-4Part 10,又叫Advanced Video Codec,因此常常稱為MPEG-4 AVC或直接叫AVC。
H.264編碼能實現非常好的壓縮比,有廣泛的適用碼率(適于從超低碼率低延遲的電話會議到高碼率的BluRay光盤和HDTV碼流),良好的硬件支持(以PSP、iPod和顯卡DXVA為代表)和眾多強大的廠商作后盾。
x264始于2003年,從當開源社區的MPEG4-ASP編碼器Xvid小有所成時開始的,經過幾年的開發,特別是Dark Shikari加入開發后,x264逐漸成為了最好的視頻編碼器。
獲取x264
x264的主頁上只用git提供源代碼。雖然官方網站不提供編譯好的版本,但是有很多人在編譯x264,特別是Win32平臺的編譯版。
- http://x264.nl 的編譯版沒有任何patch,即所謂純凈版。
- jeeb編譯版
- komisar編譯版
- rack編譯版,關注Current Patches, Where to get them, How they affect speed/output的新帖
- VFR Maniac編譯版
- xvidvideo.ru編譯版
- MythCreator的編譯版
- roozhou的支持DirectShow輸入的版本。
- 還有doom9上的Current Patches, Where to get them, How they affect speed/output和doom10上的Getting the latest x264,都會有最新的編譯版
我們一般選擇32位的最新版。
此外,可以關注由@dgwxx維護的twitter機器人@264bot,它每半小時檢查一次x264.nl更新,報告32bit和64bit版本的更新。
命令行界面的x264
我們下載到的x264.exe是一個命令行工具,不需要安裝,隨便放在哪里都能運行。雙擊x264.exe只能看到打開了一個黑色的窗口里在刷著什么,然后就沒了。x264.exe需要在命令行里輸入命令,沒有GUI。
不可否認有GUI的工具用來很方便,更容易上手,比如用的最廣泛的[http://MeGUI],此外還有ripbot、staxrip等GUI。doom9上有[1]都是各種GUI,一一試過來看看自己喜歡什么。MeGUI可以自動更新編碼常用的軟件,作為自動下載的工具倒是不錯。本篇教程主要講解命令行參數,GUI也是調用同一個x264,因此都用對應的選項。
命令行的操作
按Win+R鍵調出運行,輸入cmd,回車,出現黑底白字的窗口和幾行字,其中有 “C:\Document and Settings\User\>”表示當前所在的目錄,后面閃的光標代表等待輸入內容。
圖
假設x264.exe在E:\Encoder\文件夾,輸入
>cd /D E:\Encoder
回車
圖
改變當前目錄到E:\Encoder了。接下來,輸入
>x264
回車
圖
接下來,不用截圖說明會返回的信息了,而直接粘貼cmd里返回的字符。輸入命令會以“>”提示,看到“>”就代表此行是輸入命令并回車。
我們看到,如果只運行x264,什么都不提供給他,x264會返回一個錯誤。他告訴我們缺少輸入文件,并提示我門輸入“x264 --help”會列出選項。照他說的,加--help試試。
>x264 --help
返回
x264 core:104 r1688M 0b36c6d
Syntax: x264 [options] -o outfile infile
?
Infile can be raw (in which case resolution is required),
? or YUV4MPEG (*.y4m),
? or Avisynth if compiled with support (no).
? or libav* formats if compiled with lavf support (no) or ffms support (yes).
Outfile type is selected by filename:
.264 -> Raw bytestream
.mkv -> Matroska
.flv -> Flash Video
.mp4 -> MP4
Output bit depth: 8 (configured at compile time)
?
Options:
?
? -h, --help????????????????? List basic options
????? --longhelp????????????? List more options
????? --fullhelp????????????? List all options
?
Example usage:
?
????? Constant quality mode:
??????????? x264 --crf 24 -o <output> <input>
?
中間略...
?
Input/Output:
?
? -o, --output??????????????? Specify output file
????? --sar width:height????? Specify Sample Aspect Ratio
????? --fps <float|rational>? Specify framerate
????? --seek <integer>??????? First frame to encode
????? --frames <integer>????? Maximum number of frames to encode
????? --level <string>??????? Specify level (as defined by Annex A)
????? --quiet???????????????? Quiet Mode
?
Filtering:
?
????? Filter options may be specified in the name=value format
--vf, --video-filter <filter0>/<filter1>/... Apply video filtering to the input file
????? Available filters:
????? crop:left,top,right,bottom
????? resize:[width,height][,sar][,fittobox][,csp][,method]
????? select_every:step,offset1[,...]
這下返回了不少字符。x264先告訴我們他的版本號,再告訴我們他的基本用法是“x264 [options] -o outfile infile”。還提示我們可以輸入“--longhelp”或“--fullhelp”查看詳細選項或所有的選項。
接著輸入
>x264 --fullhelp
列出了所有選項。
x264.exe的用法是,在命令行里輸入形如
>x264 [--參數名 參數值 ...] --output 輸出文件 輸入文件
其中方括號里是可輸入可不輸入的,“...”是可以輸很多個的意思。觀察這個形式,每個參數名之前要加“--”,空格后跟此參數名的參數值;一定要有“--output”并指定輸出文件;一定要指定輸入文件,但前面沒有“--”之類的提示符號。
此外,還有短參數模式。這是為了簡化某些常用參數名設計的。一個“-”加一個字母構成一個短參數名,和與之對應的普通參數名效果一樣。注意此時這個字母區分大小寫。在--fullhelp列表里,有短參數的參數的短參數都列在此參數的前面。
實際命令實例:
>x264 --crf 22 --profile main --tune animation --preset medium --b-pyramid none -o psp.mp4 ep01.avs
調用x264編碼當前目錄下的"ep01.avs"文件,輸入"psp.264"。
>"D:\encoder tools\x264.exe" --crf 18 --tune touhou --preset slower -I 24 -o "D:\touhou\out.mkv" "D:\touhou\th9\rec.avi"
這個例子中,x264.exe、和輸入文件都不在當前目錄下,也不輸出到當前路徑,就要寫完整的路徑,如果有空格就需要在完整的路徑左右加上引號。
在Windows XP和Windows 7中,把文件拖拽到cmd里,cmd會自動把文件的完整路徑寫在命令行上的。
x264的輸入輸出文件類型
在加入了ffms/lavf后,x264可以直接輸入幾乎所有類型的片子,而不是像原來一樣必須借助于avs。下面所講的是輸入輸出的片子類型,除此之外的輸入輸出還有多pass中的stats文件、qp file、量化矩陣和tc file。
- 輸入:
x264支持輸入的文件類型有raw yuv、y4m、avs和任何可以由ffms或lavf打開的文件。raw yuv會用在64位的x264里。有ffms/lavf打開的片子會自動正確的處理vfr問題。avs和ffms/lavf輸入不需要指定片子的分辨率。
- 輸出:
x264可以輸出沒有封裝的H.264視頻流,擴展名是.264;matroska視頻,擴展名是.mkv;flash視頻,擴展名是.flv;mp4視頻,擴展名是.mp4。mkv、mp4和flv可以是vfr的。
x264通過輸出文件的擴展名判斷輸出文件類型。
x264的preset和tune系統
x264的參數繁多,開發者為了方便使用者、簡化輸入和提出編碼建議,設計了一套快速調用參數的系統。如果沒有特別的需要,請盡量使用preset和tune系統。這套開發者推薦的參數比各種道聽途說的參數更合理。
在使用了preset和tune以后,依然可以指定里面已經有的參數。手動指定的參數會覆蓋preset和tune里的參數。
--preset
通過--preset的參數調節編碼速度和質量的平衡。
--preset的值有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo。從快到慢,參數越來越EP。默認是medium。
--tune
通過--tune的參數值指定片子的類型,是和視覺優化的參數,或有特別的情況。
--tune的值有
- film:電影、真人類型;
- animation:動畫;
- grain:需要保留大量的grain時用;
- stillimage:靜態圖像編碼時使用;
- psnr:為提高psnr做了優化的參數;
- ssim:為提高ssim做了優化的參數;
- fastdecode:可以快速解碼的參數;
- zerolatency:零延遲,用在需要非常低的延遲的情況下,比如電視電話會議的編碼。
碼率控制
視頻的碼率直接影響到了片子的編碼質量。要想效果好,碼率足夠是最重要的必要條件之一。但是想實現更好的效果和控制文件的體積(碼率)之間始終是一對矛盾。這就需要我們通過實踐,在強大的編碼器的幫助下總結出合適的碼率,實現盡量好的效果。
x264有4種碼率控制方式,分別是1pass bitrate、crf、qp和2pass bitrate。其中2pass bitrate包含pass bitrate。
1pass bitrate和qp(恒定量化值)一般不推薦使用。
crf
--crf 23 (默認)
一種根據片子質量自動分配碼率的vbr碼率控制方式。一遍編碼,如果對碼率沒要求請盡量使用crf模式。
可用的值從1到51,越小編碼質量越好,碼率越高。一般使用16到24,可以為浮點。
crf并不是恒定質量的方式,同一片子同一crf值,其他參數不同可能碼率和質量能差比較大,不同的片子之間就更沒有可比性了。
2passbitrate
這種方式可以精確的得到想要的平均碼率,2pass代表需要做2次編碼,第一遍編碼x264先分析全片,得到一個stats文件和一個mbtree 文件(默認使用mbtree)。第二遍編碼以這兩個文件作參考分配合理的碼率。需要特定的碼率(或文件大小)一定要用2pass(或多pass)編碼。
除了2pass,還有多pass模式,在之前分析的基礎上再繼續分析,理論上會使碼率分配更加合理,但實際上2pass已經足夠了。
--bitrate 1000 (以1000kbps碼率為例)
>x264 --bitrate 1000 --pass 1 --tune animation --preset slower --stats "1pass.stats" -o NUL input.avs
>x264 --bitrate 1000 --pass 2 --tune animation --preset slower --stats "1pass.stats" -o output.264 input.avs
先輸入第一行,等1pass跑完之后再輸入第二行跑2pass。1pass主要為了得到1pass.stats和1pass.stats.mbtree兩個文件,2pass需要這兩個文件已完成最后的編碼,最后輸出文件。
默認情況下,1pass是以“快速”參數跑的,而不是以指定的參數跑。因此一般1pass會比2pass的速度快上很多。而這里1pass指定輸出的文件名是NUL,在Windows里,這個文件名是保留的,因此不會有任何輸出的已編碼的文件。
盡量讓1pass和2pass的視頻一致,如果改變了視頻,分析的結果就會變得比較不準確。
此外,1pass可以用crf方式跑,而且可以輸出編碼的結果,也就是說先跑個1pass看看,如果大小和預想的偏差太多,就再跑個2pass。但 由于1pass默認用“快速”參數跑,因此這里的1pass需要加上--slow-firstpass強制x264用我們給的參數跑。
>x264 --crf 20 --pass 1 --slow-firstpass --tune animation --preset slower --stats "1pass.stats" -o output1pass.264 input.avs
>x264 --bitrate 1000 --pass 2 --tune animation --preset slower --stats "1pass.stats" -o output2pass.264 input.avs
1pass會輸出3個文件:1pass.stats、1pass.stats.mbtree和output1pass.264。前兩個是分析文件,后一個是編碼的結果。如果對編碼結果不滿意,則繼續用分析的結果跑2pass。
2pass必須用bitrate模式跑,不能用crf跑。
64bit的x264
如果用了64位的Windows Vista或Windows 7,就可以用64位的x264。64位的x264大約能比32位的x264快上10%左右,能節省的時間還是比較可觀的。但是用AviSynth輸入 時,64位的x264只接受64位的AviSynth輸入,32位的x264只接受32位的AviSynth。雖然現在有64位的AviSynth和不少 常用的濾鏡,但是大多數人還是愿意用32位的AviSynth。那么如何用讓64位的x264配合32位的AviSynth呢?
方法是用pipe。用命令行工具(如ffmpeg、mencoder或avs2yuv)打開avs,讓輸出的raw yuv畫面直接輸入給x264,期間不產生中間文件。這個操作也是在命令行里實現的。
用ffmpeg輸入
先下載ffmpeg的Windows編譯版,可以用static link版本。目前ffmpeg在Windows只有32位的編譯版。和x264一樣,ffmpeg放在任何目錄里都能運行,假設和x264、要進行編碼的input.avs放在一個目錄里。
>ffmpeg -i input.avs -f yuv4mpegpipe -an -v 0 - | x264 [options] --demuxer y4m -o output.264 -
先用ffmpeg打開input.avs,并不指定輸出的文件,而是以“-”代替輸出的文件。后面寫“|”,再寫x264,x264的選項和輸出文件寫法不變,但是輸入文件寫“-”。
用mencoder輸入
mencoder有很多有價值的濾鏡,用起來也很方便。libx264可以編譯進mencoder本身,和單獨的x264效果一樣。mencoder也可以打開avs文件,pipe給64位的x264。mplayer-ww的命令行版里就帶有mencoder。
同樣假設mencoder、x264和要編碼的的input.avs(1280x720)在一個目錄里。
>mencoder input.avs -vf format=yv12 -of rawvideo -ovc raw -nosound -o - | x264 [options] --input-res 1280x720 --input-csp yv12 -o output.264 -
mencoder部分不同,x264部分和用ffmpeg時一樣。
用avs2yuv輸入
avs2yuv本來是為了給linux上wine來用的,因為AviSynth是運行在Windows的,在linux里必須wineavs2yuv來打開avs,再pipe給x264。當然也可以用來pipe給64位的x264。
同樣假設avs2yuv、x264和要編碼的的input.avs在一個目錄里。
>avs2yuv input.avs - | x264 [options] --demuxer y4m -o output.264 -
avs2yuv的輸出格式默認是yuv4mpeg,x264用y4m格式解碼即可從中讀取分辨率,所以無須再用--input-res指定分辨率。
以上介紹了3種方法,個人比較傾向于用ffmpeg。2pass的編碼也是像上面所講的方法一樣。
x264壓制的自動化
雖然MeGUI等程序實現了x264壓制的批量化,但并無法實現crf 1st pass + bitrate 2nd pass的自動2pass,也無法實現1st pass和2nd pass使用不同avs腳本。
為此SAPikachu編寫了Python腳本encx264,實現了以下功能:
- 支持1Pass crf + 2Pass bitrate模式,自動獲取crf出來的碼率作為2pass參數。也可設定2pass碼率的比例,自動計算2nd pass碼率功能。
- 自動記錄壓制log。
- 可自定義多套預置參數。
- 可分別使用不同腳本跑1st和2nd pass。如1st pass使用較快的濾鏡,2nd pass再使用速度慢效果好的濾鏡,犧牲一定精度來提高速度。
- 支持腳本自動升級最新版。
下載、討論、反饋請前往論壇討論發布專用貼。
DXVA
參考主條目: DXVA和psp
DXVA(DirectX Video Accelaration)通常被稱為硬解,是在Windows上用顯卡解碼H.264等編碼視頻的方式。AMD的顯卡方面,HD2xxx以上的系列都可 以DXVA;nVidia的顯卡方面,GeForce8000以上的系列都可以DXVA。
符合一定條件的H.264編碼的片子才能正常的DXVA。由于H.264的復雜性,用比較老的CPU解碼720p和1080p通常比較吃 力,因此720p和1080p的片子能否DXVA常常成為矛盾的焦點。為了讓大多數人都能正常的看到片子,建議盡量使用能夠DXVA的參數壓制。
RTP 協議
概述:
實時傳送協議(Real-time Transport Protocol或簡寫RTP,也可以寫成RTTP)是一個網絡傳輸協議,它是由IETF的多媒體傳輸工作小組1996年在RFC 1889中公布的。
RTP協議詳細說明了在互聯網上傳遞音頻和視頻的標準數據包格式。它一開始被設計為一個多播協議,但后來被用在很多單播應用中。RTP協議常用于流媒體系統(配合RTCP協議或者RTSP協議)。因為RTP自身具有Time stamp所以在ffmpeg中被用做一種formate.
RTP協議格式:
??? 0?????????????????? 1?????????????????? 2?????????????????? 3
??? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |V=2|P|X|? CC?? |M|???? PT????? |?????? sequence number???????? |
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |?????????????????????????? timestamp?????????????????????????? |
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |?????????? synchronization source (SSRC) identifier??????????? |
?? +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
?? |??????????? contributing source (CSRC) identifiers???????????? |
?? |???????????????????????????? ....????????????????????????????? |
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
上圖引自rfc3550,由上圖中可知道RTP報文由兩個部分構成--RTP報頭和RTP的負載:
RTP報文由兩部分組成:報頭和有效載荷。RTP報頭格式如圖6.7所示,其中:
1.V:RTP協議的版本號,占2位,當前協議版本號為2。
2. P:填充標志,占1位,如果P=1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷的一部分。
3. X:擴展標志,占1位,如果X=1,則在RTP報頭后跟有一個擴展報頭。
4.? CC:CSRC計數器,占4位,指示CSRC 標識符的個數。
5. M: 標記,占1位,不同的有效載荷有不同的含義,對于視頻,標記一幀的結束;對于音頻,標記會話的開始。
6. PT: 有效載荷類型,占7位,用于說明RTP報文中有效載荷的類型,如GSM音頻、JPEM圖像等,在流媒體中大部分是用來區分音頻流和視頻流的,這樣便于客戶端進行解析。
7. 序列號:占16位,用于標識發送者所發送的RTP報文的序列號,每發送一個報文,序列號增1。這個字段當下層的承載協議用UDP的時候,網絡狀況不好的時 候可以用來檢查丟包。同時出現網絡抖動的情況可以用來對數據進行重新排序,在helix服務器中這個字段是從0開始的,同時音頻包和視頻包的 sequence是分別記數的。
8. 時戳(Timestamp):占32位,時戳反映了該RTP報文的第一個八位組的采樣時刻。接收者使用時戳來計算延遲和延遲抖動,并進行同步控制。
9. 同步信源(SSRC)標識符:占32位,用于標識同步信源。該標識符是隨機選擇的,參加同一視頻會議的兩個同步信源不能有相同的SSRC。
10. 特約信源(CSRC)標識符:每個CSRC標識符占32位,可以有0~15個。每個CSRC標識了包含在該RTP報文有效載荷中的所有特約信源。
如果擴展標志被置位則說明緊跟在報頭后面是一個頭擴展,其格式如下:
??? 0?????????????????? 1?????????????????? 2?????????????????? 3
??? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |????? defined by profile?????? |?????????? length????????????? |
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |??? ????????????????????header extension?????????????????????? |
?? |???????????????????????????? ....????????????????????????????? |
RTP協議的用途:
概述中已經基本闡述了RTP協議的用途了,其主要用于在互聯網上傳遞音頻和視頻的標準數據包。在當前三網融合中RTP可以用來承載TS流,進行電視 媒體數據的傳播。RTP可以用來傳送像TS流這種自身已經具有formate的媒體流,同時也可以用來承載AVC,AAC等去除了fromate的媒體 流,這時rtp協議可被看做為一種formate,這種形式最少常見于helix 流媒體服務器的rtp流。其控制流由RTSP協議來提供。
RTP協議的使用:
RTP的使用實例之一如上圖:
上面是某省IPTV2.0早期的一個數據包的情況。從包中可以看出RTP是怎么和RTSP配合一起使用的。從包402到411為RTSP的協商過程,RTSP在PLAYer命令后數據包就到來。緊跟其后412包就是一個mpeg 的PES包,它是有由rtp來承載的TS來形成。從在420包中就可以更加清析的看出這個RTP流的情況。其PT即payloadtype為mpeg2 transport streams 也就是ts流,其SSRC為:0x65737D6c,其Seq號為15764,從中也可以看出對于一個RTP流其SEQ號可以開始于一個隨機的數值,但是 肯定是逐包遞增的。下圖為420包的展開圖:
從中可以看出承載RTP的為UDP的數據流這個包中有x標志位為1則說明其有 headerextensions.其header extensions為最下面。extension 的 profile為23128,長度為:2內容如上圖最后兩部分。
媒體格式分析之flv -- 基于FFMPEG
本來是應該先寫一個媒體文件格式的簡單講解的,還沒來得及寫,以后再寫。今天就先根據ffmpeg的flv.c的flv_demux這個結構體來講解一下當前比較流行的媒體格式flv.
FLV 是FLASH VIDEO的簡稱,FLV流媒體格式是隨著Flash MX的推出發展而來的視頻格式。由于它形成的文件極小、加載速度極快,使得網絡觀看視頻文件成為可能.當前主流的媒體網站像國內的優酷、國外youtube其標清格式的文件均采用flv的格式。
FLV文件結構解析
FLV是一個二進制文件,其文件格式如下圖 ,由文件頭(FLVheader)和很多tag組成。tag又可以分成三類:audio,video,script,分別代表音頻流,視頻流,腳本流(關鍵字或者文件信息之類)。
FLV Header
FLV的Header信息一般比較簡單,包括文件類型之類的全局信息。如下圖中解析:
文件類型3bytes 總是FLV(0x46 0x4C 0x56),否則就不是在ffmpeg中在沒有指定文件格式的情況下,也是通過這個字段來探測文件是否屬于FLV格式的。
版本1byte 一般是0x01,表示FLV version 1
流信息1byte 倒數第一bit是1表示有視頻,倒數第三bit是1表示有音頻,其他都應該是0(有些軟件如flvtool2可能造成倒數第四bit是1,不過也沒發現有什么不對)
header長度4bytes 整個文件頭的長度,一般是9(3+1+1+4),當然頭部字段也有可能包含其它信息這個時間其長度就不是9了。
FLV Body
FLV body就是由很多tag組成的,一個tag包括下列信息:
????? previoustagsize 4bytes 前一個tag的長度,第一個tag就是0
tag類型1byte 共分為三類:
* 8 -- 音頻tag
* 9 -- 視頻tag
* 18 -- 腳本tag
數據區長度3bytes 時間戳3bytes 單位毫秒同時還有1bytes的擴展時間戳,放在最高位,大部分時間時間戳為媒體的dts信息,如果是腳本tag就是0
streamsID 3bytes 總是0(不知道干啥用)
數據區:根據不同的tag類型就有不同的數據區
腳本tag :
腳本tag一般是用文本方式表示,如下圖flv的metadata信息:
從中可以看出是通過文本的方式來標記的,其解析后其header信息為:
從中可以看出其type為18。time stamp為0.data size為33638.
metadata tag data信息解析后為:
其中有一些媒體信息:
例如視頻的:高和寬它的codec id。幀率。音頻的信息例如:音頻的samplerate,codec id,sample size及是否立體聲。還有整個文件的大小等等。
音頻的tag信息:
音頻的tag信息如下圖:
其中time stamp 為0是因為其為第一個音頻tag.
視頻tag
這是文件中的第6個tag所以其time stamp不為0。因為其為視頻tag所以其type為9。
ffmpeg中的flv文件格式解析的實現:
其中flv_read_header主要是從文件中讀取一些頭信息,同時作一些初始化化的工作
static int flv_read_header(AVFormatContext*s,AVFormatParameters *ap)
{
???????? ……
??? url_fskip(s->pb, 4); //將flv的頭去掉。
??? flags = get_byte(s->pb);//讀出flv的video和audio flag信息。
???????? ……?
??????? if(flags &FLV_HEADER_FLAG_HASVIDEO){
??????? if(!create_stream(s, 0))? //創建視頻流
??????????? returnAVERROR(ENOMEM);
??? }
??? if(flags & FLV_HEADER_FLAG_HASAUDIO){
??????? if(!create_stream(s, 1)) //創建音頻流
??????????? returnAVERROR(ENOMEM);
??? }
??? offset = get_be32(s->pb); //獲取文件頭長度
??????? ……
}
其它tag的讀取:
static int flv_read_packet(AVFormatContext *s, AVPacket*pkt)
{
???? ……
for(;;url_fskip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
??? pos = url_ftell(s->pb);
??? type = get_byte(s->pb); //獲取tag的類型,前面已經提到flv的tag大概有以下三種 :FLV_TAG_TYPE_AUDIO = 0x08,FLV_TAG_TYPE_VIDEO =0x09,FLV_TAG_TYPE_META? = 0x12,
??? size = get_be24(s->pb);//獲取tag的長度
??? dts = get_be24(s->pb);
??? dts |= get_byte(s->pb) << 24; //計算tag的timestamp也就是dts信息
??? ……
??? if (type == FLV_TAG_TYPE_AUDIO) { //判斷是否為audio tag
?????? ……
???????? } else if (type ==FLV_TAG_TYPE_VIDEO) {//判斷是否為video tag
?????? ……
??????????????if ((flags & 0xf0) == 0x50) /* video info / command frame */
??????????? goto skip;
??? } else {
??????? if (type == FLV_TAG_TYPE_META&& size > 13+1+4)//判斷是否為meta tag,如果是meta信息則會將信息存放在一個map表中。
???????? ……
}
版權所有:博水。轉載請注明出處:http://www.cnblogs.com/qingquan/
SDP 協議分析
一、SDP協議介紹
SDP 完全是一種會話描述格式 ― 它不屬于傳輸協議 ― 它只使用不同的適當的傳輸協議,包括會話通知協議(SAP)、會話初始協議(SIP)、實時流協議(RTSP)、MIME 擴展協議的電子郵件以及超文本傳輸協議(HTTP)。SDP協議是也是基于文本的協議,這樣就能保證協議的可擴展性比較強,這樣就使其具有廣泛的應用范圍。SDP 不支持會話內容或媒體編碼的協商,所以在流媒體中只用來描述媒體信息。媒體協商這一塊要用RTSP來實現.
二、SDP協議格式
SDP描述由許多文本行組成,文本行的格式為<類型>=<值>,<類型>是一個字母,<值>是結構化的文本串,其格式依<類型>而定。
<type>=<value>[CRLF]
常見的fields有:
三、SDP協議例子:
下面是一個helix 流媒體服務器的RTSP協議中的SDP協議:
v=0 //SDP version
// o field定義的源的一些信息。其格式為:o=<username><sess-id> <sess-version> <nettype> <addrtype><unicast-address>
o=- 1271659412 1271659412 IN IP4 10.56.136.37 s=<Notitle>
i=<No author> <No copyright>? //session的信息
c=IN IP4 0.0.0.0 //connect 的信息,分別描述了:網絡協議,地址的類型,連接地址。
c=IN IP4 0.0.0.0
t=0 0 //時間信息,分別表示開始的時間和結束的時間,一般在流媒體的直播的時移中見的比較多。
a=SdpplinVersion:1610641560 //描述性的信息
a=StreamCount:integer;2 //用來描述媒體流的信息,表示有兩個媒體流。integer表示信息的格式為整數。
a=control:*
a=DefaultLicenseValue:integer;0 //License信息
a=FileType:string;"MPEG4" 用來描述媒體流的信息說明當前協商的文件是mpeg4格式的文件
a=LicenseKey:string;"license.Summary.Datatypes.RealMPEG4.Enabled"
a=range:npt=0-72.080000? //用來表示媒體流的長度
m=audio 0 RTP/AVP 96 //做為媒體描述信息的重要組成部分描述了媒體信息的詳細內容:表示session的audio是通過RTP來格式傳送的,其payload值為96傳送的端口還沒有定。
b=as:24 //audio 的bitrate
b=RR:1800
b=RS:600
a=control:streamid=1? //通過媒體流1來發送音頻
a=range:npt=0-72.080000 //說明媒體流的長度。
a=length:npt=72.080000
a=rtpmap:96 MPEG4-GENERIC/32000/2 //rtpmap的信息,表示音頻為AAC的其sample為32000
a=fmtp:96profile-level-id=15;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1210//config為AAC的詳細格式信息
a=mimetype:string;"audio/MPEG4-GENERIC"
a=Helix-Adaptation-Support:1
a=AvgBitRate:integer;48000
a=HasOutOfOrderTS:integer;1
a=MaxBitRate:integer;48000
a=Preroll:integer;1000
a=OpaqueData:buffer;"A4CAgCIAAAAEgICAFEAVABgAAAC7gAAAu4AFgICAAhKIBoCAgAEC"
a=StreamName:string;"Audio Track"
下面是video的信息基本和audio的信息相對稱,這里就不再說了。
m=video 0 RTP/AVP 97
b=as:150
b=RR:11250
b=RS:3750
a=control:streamid=2
a=range:npt=0-72.080000
a=length:npt=72.080000
a=rtpmap:97 MP4V-ES/2500
a=fmtp:97 profile-level-id=1;
a=mimetype:string;"video/MP4V-ES"
a=Helix-Adaptation-Support:1
a=AvgBitRate:integer;300000
a=HasOutOfOrderTS:integer;1
a=Height:integer;240 //影片的長度
a=MaxBitRate:integer;300000
a=MaxPacketSize:integer;1400
a=Preroll:integer;1000
a=Width:integer;320? //影片的寬度
a=OpaqueData:buffer;"AzcAAB8ELyARAbd0AAST4AAEk+AFIAAAAbDzAAABtQ7gQMDPAAABAAAAASAAhED6KFAg8KIfBgEC"
a=StreamName:string;"Video Track"
I,P,B幀和PTS,DTS的關系
基本概念:
I frame :幀內編碼幀 又稱intra picture,I 幀通常是每個 GOP(MPEG 所使用的一種視頻壓縮技術)的第一個幀,經過適度地壓縮,做為隨機訪問的參考點,可以當成圖象。I幀可以看成是一個圖像經過壓縮后的產物。
P frame: 前向預測編碼幀 又稱predictive-frame,通過充分將低于圖像序列中前面已編碼幀的時間冗余信息來壓縮傳輸數據量的編碼圖像,也叫預測幀;
B frame: 雙向預測內插編碼幀 又稱bi-directionalinterpolated prediction frame,既考慮與源圖像序列前面已編碼幀,也顧及源圖像序列后面已編碼幀之間的時間冗余信息來壓縮傳輸數據量的編碼圖像,也叫雙向預測幀;
PTS:Presentation Time Stamp。PTS主要用于度量解碼后的視頻幀什么時候被顯示出來
DTS:Decode Time Stamp。DTS主要是標識讀入內存中的bit流在什么時候開始送入解碼器中進行解碼。
在沒有B幀存在的情況下DTS的順序和PTS的順序應該是一樣的。
IPB幀的不同:
I frame:自身可以通過視頻解壓算法解壓成一張單獨的完整的圖片。
P frame:需要參考其前面的一個I frame 或者B frame來生成一張完整的圖片。
B frame:則要參考其前一個I或者P幀及其后面的一個P幀來生成一張完整的圖片。
兩個I frame之間形成一個GOP,在x264中同時可以通過參數來設定bf的大小,即:I 和p或者兩個P之間B的數量。
通過上述基本可以說明如果有B frame 存在的情況下一個GOP的最后一個frame一定是P.
DTS和PTS的不同:
DTS主要用于視頻的解碼,在解碼階段使用.PTS主要用于視頻的同步和輸出.在display的時候使用.在沒有B frame的情況下.DTS和PTS的輸出順序是一樣的.
例子:
下面給出一個GOP為15的例子,其解碼的參照frame及其解碼的順序都在里面:
如上圖:I frame 的解碼不依賴于任何的其它的幀.而p frame的解碼則依賴于其前面的I frame或者P frame.B frame的解碼則依賴于其前的最近的一個I frame或者P frame 及其后的最近的一個P frame.
RTSP 協議分析 (一)
RTSP 協議分析
1.概述:
?RTSP(Real Time Streaming Protocol),實時流傳輸協議,是TCP/IP協議體系中的一個應用層協議,由哥倫比亞大學、網景和RealNetworks公司提交的IETF RFC標準。該協議定義了一對多應用程序如何有效地通過IP網絡傳送多媒體數據。類似HTTP協議的流控制協議。它們都使用純文本來發送信息,而且 rtsp協議的語法也和HTTP類似,和HTTP協議相比RTSP協議所不同的地方是,RTSP協議是有狀態的協議,而HTTP是無狀態的協議。RTSP 通過維護一個session來維護其狀態的轉換。RTSP協議的默認端口是554,默認的承載協議為TCP。
2.RTSP的特性:
(1).流控分離:從控制邏輯上來說RTSP和FTP相似,控制流和數據流是分開的。
(2).可擴展性:因為RTSP協議是基于文本的協議所以其具有較強的可擴展性。
(3).安全:RTSP使用網頁安全機制。
3.RTSP 協議格式:
請求命令的格式為:
METHOD URL CR LF
Field1:value CR LF
Field2:value CR LF
......
Fieldn:value CR LF
CR LF
應答的格式為:
RTSP/major_version.minor_version status CR LF
Field1:value CR LF
Field2:value CR LF
......
Fieldn:value CR LF
CR LF
4.RTSP的主要命令:
5.RTSP命令的狀態轉換表
6.RTSP狀態碼
Status-Code = "100" ;Continue
| "200" ; OK
| "201" ; Created
| "250" ; Low onStorage Space
| "300" ; MultipleChoices
| "301" ; MovedPermanently
| "302" ; MovedTemporarily
| "303" ; See Other
| "304" ; NotModified
| "305" ; Use Proxy
| "400" ; Bad Request
| "401" ;Unauthorized
| "402" ; PaymentRequired
| "403" ; Forbidden
| "404" ; Not Found
| "405" ; Method NotAllowed
| "406" ; NotAcceptable
| "407" ; ProxyAuthentication Required
| "408" ; RequestTime-out
| "410" ; Gone
| "411" ; LengthRequired
| "412" ;Precondition Failed
| "413" ; RequestEntity Too Large
| "414" ; Request-URIToo Large
| "415" ; UnsupportedMedia Type
| "451" ; ParameterNot Understood
| "452" ; ConferenceNot Found
| "453" ; Not EnoughBandwidth
| "454" ; Session NotFound
| "455" ; Method NotValid in This State
| "456" ; HeaderField Not Valid for Resource
| "457" ; InvalidRange
| "458" ; ParameterIs Read-Only
| "459" ; Aggregateoperation not allowed
| "460" ; Onlyaggregate operation allowed
| "461" ; Unsupportedtransport
| "462" ; Destinationunreachable
| "500" ; InternalServer Error
| "501" ; NotImplemented
| "502" ; Bad Gateway
| "503" ; ServiceUnavailable
| "504" ; GatewayTime-out
| "505" ; RTSPVersion not supported
| "551" ; Option notsupported
| extension-code
extension-code = 3DIGIT
Reason-Phrase = *<TEXT,excluding CR, LF
<下一篇將給出RTSP協議的實例分析>
RTSP協議分析(二)
以下是某省IPTV的RTSP協商過程:
DESCRIBErtsp://118.122.89.27:554/live/ch10083121594790060557.sdp?playtype=1&boid=001&backupagent=118.122.89.27:554&clienttype=1&time=20100929182111+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=123&mediaid=ch10083121594790060557&ctype=2&TSTVTimeLife=1800&contname=&authid=0&UserLiveType=1&nodelevel=3RTSP/1.0
/媒體URL
Accept: application/sdp
//協商用于描述媒體信息協議
CSeq: 1
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
//User Agnet信息,顯示是中興的服務器,1.0的版本。如果是Helix服務器的話會有Helix 服務器的標識。
x-NAT:2.1.1.100:20081
//主要用于NAT穿透
x-zmssRtxSdp: yes
RTSP/1.0 200 OK
//應答編號
Server: ZXUSS100 1.0
Cache-Control: no-cache
Content-Base:rtsp://118.122.89.27:554/live/ch10083121594790060557.sdp/
Content-Length: 320
//內容長度信息
Content-Type: application/sdp
//描述內容信息所用的協議
CSeq: 1
Date: Wed, 29 Sep 2010 10:20:38 GMT
Expires: Wed, 29 Sep 2010 10:20:38 GMT
// SDP 描述信息
v=0
o=- 296874273 1 IN IP4 118.122.89.27
s=envivio
c=IN IP4 0.0.0.0
b=AS:1500
t=0 0
a=range:clock=20100929T095038.00Z-20100929T102038.00Z
m=video 5140 RTP/AVPF 33 96
a=control:trackID=2
a=rtpmap:33 MP2T/90000
a=3GPP-Adaptation-Support:5
a=rtcp-fb:33 nack
a=rtpmap:96 rtx/90000
a=fmtp:96 apt=33;rtx-time=0
SETUPrtsp://118.122.89.27:554/live/ch10083121594790060557.sdp/trackID=2 RTSP/1.0
//用于建立RTSP連接,協商傳輸用的協議。
CSeq: 2
3GPP-Adaptation:url=rtsp://118.122.89.27:554/live/ch10083121594790060557.sdp/trackID=2;size=1061400;target-time=2200
Transport:MP2T/RTP/UDP;unicast;destination=2.1.1.100;client_port=8360-8361,MP2T/RTP/TCP;unicast;destination=2.1.1.100;interleaved=0-1,MP2T/UDP;unicast;destination=2.1.1.100;client_port=8360-8361,MP2T/TCP;unicast;destination=2.1.1.100;interleaved=0-1
// MP2T/RTP/UDP表示是TS流用于RTP打包,基于UDP傳輸。MP2T/RTP/TCP表示是TS流用于RTP打包,基于TCP。
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 2
Date: Wed, 29 Sep 2010 10:20:38 GMT
Expires: Wed, 29 Sep 2010 10:20:38 GMT
Session: 65565885
Transport:MP2T/RTP/UDP;unicast;destination=2.1.1.100;client_port=8360-8361;server_port=13306-13307;source=118.122.89.29
// 通過協商MP2T/RTP/UDP表示是TS流用于RTP打包,基于UDP傳輸。server端端口:13306-13307。client端端口:8360-8361
3GPP-Adaptation:url=rtsp://118.122.89.27:554/live/ch10083121594790060557.sdp/trackID=2;size=1061400;target-time=2200
PLAYrtsp://118.122.89.27:554/live/ch10083121594790060557.sdp?playtype=1&boid=001&backupagent=118.122.89.27:554&clienttype=1&time=20100929182111+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=123&mediaid=ch10083121594790060557&ctype=2&TSTVTimeLife=1800&contname=&authid=0&UserLiveType=1&nodelevel=3RTSP/1.0
//播放視頻。對于有些視頻可能會分別要對音頻視頻進行play。
CSeq: 3
Session: 65565885
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
Scale: 1.0
Range: npt=end-
//npt=end-在IPTV2.0里面有其自身的定義(可參看上海電信IPTV2.0標準)
RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 3
Range: npt=end-
Scale: 1.0
Session: 65565885
RTP-Info: url=rtsp://118.122.89.29:13306/live/ch10083121594790060557.sdp/trackID=2
......
PLAYrtsp://118.122.89.27:554/live/ch10083121594790060557.sdp?playtype=1&boid=001&backupagent=118.122.89.27:554&clienttype=1&time=20100929182111+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=123&mediaid=ch10083121594790060557&ctype=2&TSTVTimeLife=1800&contname=&authid=0&UserLiveType=1&nodelevel=3RTSP/1.0
//play的另外一種用法。用于快進和快退。
CSeq: 43
Session: 65565885
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
Scale: -32.0
//Scale: -32.0,表示以32倍速快退。Scale:32.0,表示以32倍速快進。
Range: npt=now-
RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 43
Range: clock=20100929T102609.02Z-20100929T095637.75Z
Scale: -32.0
Session: 65565885
RTP-Info:url=rtsp://118.122.89.36:10084/live/ch10083121594790060557.sdp/trackID=2;seq=22277;rtptime=1792329138
GET_PARAMETERrtsp://118.122.89.27:554/live/ch10083121594790060557.sdp?playtype=1&boid=001&backupagent=118.122.89.27:554&clienttype=1&time=20100929182111+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=123&mediaid=ch10083121594790060557&ctype=2&TSTVTimeLife=1800&contname=&authid=0&UserLiveType=1&nodelevel=3RTSP/1.0
//獲取當前的一些播放參數。
CSeq: 44
Session: 65565885
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
x-Timeshift_Range
//請求時移的范圍
x-Timeshift_Current
//獲取當前的時間點
RTSP/1.0 200 OK
//返回當前的媒體信息。
Server: ZXUSS100 1.0
CSeq: 44
Session: 65565885
x-Timeshift_Range: clock=20100929T095638.83Z-20100929T102638.83Z
x-Timeshift_Current:clock=20100929T102530.20Z;rtptime=1788844914
中間省去了45,46,47三個包。通過CSeq: 48字段可以看出來
PLAYrtsp://118.122.89.27:554/live/ch10083121594790060557.sdp?playtype=1&boid=001&backupagent=118.122.89.27:554&clienttype=1&time=20100929182111+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=123&mediaid=ch10083121594790060557&ctype=2&TSTVTimeLife=1800&contname=&authid=0&UserLiveType=1&nodelevel=3RTSP/1.0
用于恢復正常的播放速度。
CSeq: 48
Session: 65565885
User-Agent:ZTE Ltd.co RTSP protocal verion 1.0 guid-2.1.1.100/B519D290-C0EC-EE35-7368-893BE4C0B347
Scale: 1.0
Range: npt=beginning-
RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 48
Range: clock=20100929T095730.00Z-20100929T102730.61Z
//可以時移的范圍。
Scale: 1.0
Session: 65565885
RTP-Info: url=rtsp://118.122.89.36:10084/live/ch10083121594790060557.sdp/trackID=2;seq=39900;rtptime=1637595010
<中間在Descript應答中所用的SDP協議將會在以后中描述>
ffmpeg/ffplay vc6 源碼剖析
ffmpeg/ffplay是當今多媒體領域的王者,很多很多的人想研究學習 ffmpeg/ffplay,但苦于ffmpeg/ffplay龐大的代碼量,令人望而生畏。為幫助更多的人研習ffmpeg/ffplay,在保持 ffmpeg/ffplay體系架構的完整性的前提下,把ffmpeg/ffplay大規模的瘦身后,研習門檻一下子降低了n多個數量級。附件一個是對瘦身后的ffmpeg/ffplay的代碼完整的剖析pdf文檔,另一個是瘦身后的ffmpeg/ffplay的完整源代碼,最大化幫助各位網友研究學習ffmpeg/ffplay。
?
特別注意:
1:如果VC6 debug模式跑出錯誤了,就用VS2005跑。
2:重新上傳了ffsrc.7z,修正了一個內存泄露,改正了黑屏的問題(不好意思,以前上傳的時候不小心,傳的是debug的版本)。
?
pdf檔下載地址:http://files.cnblogs.com/mcodec/ffdoc.7z
源代碼下載地址:http://files.cnblogs.com/mcodec/ffsrc.7z
代碼糟糕之路(一)--- 破窗理論
版權保留,轉載請注明出處:http://www.cnblogs.com/qingquan
這一段想總結一下之前的東西,因為之前做了一個比較快的項目,項目不大,但人員流動性比較大出現了一些比較典型的現象,在此將這些現象記錄下來,以備以后查看同時也和大家一起討論一下。
破窗理論:一個房子如果窗戶破了,沒有人去修補,隔不久,其它的窗戶也會莫名其妙地被人打破;一面墻,如果出現一些涂鴉沒有被清洗掉,很快的,墻上就布滿了亂七八糟、不堪入目的東西;一個很干凈的地方,人們不好意思丟垃圾,但是一旦地上有垃圾出現之后,人就會毫不猶疑地拋,絲毫不覺羞愧。
在日常的代碼工作中,尤其在對新加入公司的員工,因為他們對當前公司的代碼規范不是很熟悉。在代碼編碼過程中可能有意無意的帶來了他前一個公司的一 些編碼習慣,但這些編碼習慣可能和當前公司的編碼習慣不是很一樣。例如:當前A公司的C語言編碼規范是采用把起始大括號放在行尾,而把結束大括號放在行 首。縮進采用4個空格的方法。但是新來的一個員工,因為沒有很好的遵守規范帶來了之前編碼習慣,這時他有可能在更改一段之前代碼的時候:
if (x is true) {
?? we do y
}
將這段這段代碼改為:
if (x is true) {
??? do
??? {
??????? body of do-loop
??? } while (condition);
}
這樣整個代碼風格就開始發生變化,之后由于一不小心將4個空格按成一個tab鍵,這樣整個代碼風格就開始面目全非。
之后又有一次因為緊急情況,因為工作時間緊急抽調一個新人對上面的代碼進行修改。因為新人可能也沒有考慮整個代碼的風格,對命名規范吃的不是很準 確,如果他在他的編輯器里面把tab鍵的長度設置為8個空格這樣看起來整個代碼已經是混亂一片。這時如果再有第三個人更改這段代碼的時候,公司的代碼規范的約束力已經無形中被削弱了很多。這樣代碼混亂的情況就會從代碼格式進而擴展的命名規則,代碼注釋等方面。這樣這段代碼再經過幾個人的更改而沒有整理和重 構的情況下將很快會變的異常混亂。這段代碼就會像一個破了一塊玻璃的房子一樣,很快變的面目全非。
下一篇可能著重從高人員流動情況下對代碼的影響。
QtModel/View 概論(-)
Model-View-Controller(MVC), 是從Smalltalk發展而來的一種設計模式,常被用于構建用戶界面。它強制性的使應用程序的輸入、處理和輸出分開。
在Qt中引入了一個MVC的變體---model/view結構。這個結構依然是把數據存儲與數據表示進行了分離,它與MVC都基于同樣的思想,但它更簡單一些。這種分離使得在幾個不同的view上顯示同一個數據成為可能,也可以重新實現新的view,而不必改變底層的數據結構。為了更靈活的對用戶 輸入進行處理,引入了delegate這個概念。它的好處是,數據項的渲染與編程可以進行定制。其具體工作機制如下圖:
從上圖可看出,Model直接讀取數據,View可以直接顯示數據,也可以顯示經過Delegate處理后的數據。同時用戶可以直接通過 Delegate直接編輯數據通過model存入數據文件中。models,views,delegates之間通過信號,槽機制來進行通訊。
工作機制:
傳統中View只用來負責數據顯示,因此在view創建時并不需要model只有當其顯示信息的時候才會用到model。model通過QAbstractItemMode提供統一的接口,view會調用model的index來獲得一個indexmodel,然后再通過indexmodel來獲得想要得到的data.
model負責從數據集里面選取合適的數據提供給View因此model可以充當數據的選擇和過濾器,另一方面可以接收Delegate發回的信息更新數據集中的數據信息。
Deletegate是由View層通過各種signal或者event事件引發,實現數據的更改并通過Model寫入數據集中。
?
?
?
?
CodeReview(-)
Code Review
做軟件開發的時間轉眼也有三年有余,所在的團隊也使用了各種各樣的代碼質量控制方法,個人覺得Code Review是一個最有效的方法,同時也是“性價比”最高的代碼質量控制方法。現將個人的一些觀點和看法總結一下
什么是Code Review
Code Review 中文的翻譯方式有很多種“代碼審查”,“代碼評審”,“代碼走查”等,個人更喜歡“代碼走查”這種翻譯。代碼走查是一個流程,從開發人員在一個開發階段寫好代碼后開始,之后需要別人以發現bug和技術交流為目的review一下他的代碼。它是集代碼審查,找出問題,改進代碼和改后督查為一體的完整的流程。代碼走查一般在代碼剛剛出爐為最好,因為在這個時候也是代碼重構和調整的最佳時候。
Code Review的目的及內容
功能性Review:
通 過Review檢查當前代碼是否全部實現了需求里面全部的功能點,且功能正確。找出代碼中的bug,每個人在寫和讀代碼的時候都有固有的習慣,這樣的一些 習慣往往會影響代碼的質量。比如:我們在代碼編寫過程中都出現過類似的問題,自己代碼中的問題自己無論看了多少遍都發現不了,但別人一眼就能發現問題。出現這樣的情況并不是說寫代碼的人水平不高而是個人編程中的“無意識”錯誤。當然這也就是結隊編程的妙處。
可讀性Review:
代碼做為軟件開發過程中最實時的文檔,同時為了以后維護方便一定要有高度的可讀性。可讀性檢查主要檢查代碼風格是否嚴格按照系統代碼風格規定,代碼中是否經過充分的重構消除了其中冗余重復的代碼。代碼結構是否合理。
分享技術知識:
“三 人行必有我師”每個人的代碼都有值得別人學習的地方,而且團隊中各個成員水平高低不一,通過代碼Review使水平高的人的技術逐漸流向水平低的人培養了 新人。同時代碼編寫者向團隊中的其他人介紹自己所用的技術和方法,這樣一方面使各種技術在團隊中得到共享。筆者在當前的公司里面遇到這樣一個案例:
團 隊1在之前的項目開發中用到freetype做中文排版,但是當時沒有做代碼review。之后團隊2也用到了freetype方面的知識但因為不知道團隊1有freetype方面的知識,結果團隊2又花費了大量的時間和精力去重新研究和學習freetype。這樣大大延緩了項目的時間進度。
互為backup:
通過代碼Review使更多的人了解當前模塊的功能,這樣減少了因人員流失而導致對項目產生的沖擊。
待續......
?
CodeReview(二)
態度決定一切:
Code Review 做為軟件開發中的一個重要環節,也是人參與和交互度比較高的一個環節,參與者對CodeReview的態度將會很大程度上影響Code Review的效果。而程序員又是一群不善于同別人交流的一個群體,這樣在Code Review的過程中可能因為對這件事的認識程度和態度的不同而會產生很大差距:
對于代碼的講解者來說,一些很有經驗的程序員往往因為對Code Review的目的等方面認識不足容易犯這樣一種錯誤,認為自己的代碼不會有問題,這次Code Review就是給別人傳道授業解惑的。這樣會出現整個Code Review的過程基本拋棄了Code完全只講他實現的思路和方法,完全成為了一個知識講座,但要知道整體設計和具體實現還有很大不同。你的宏觀思路很正 確并不代表你的代碼就沒有一點問題。對于一些初來乍到的年輕人則會走向另一個極端,一說Code Review就像讓他去刑場一樣。就是為了去接受審判而去Code Review,完全依賴于自己的代碼,沒有把自己在這個過程中所學到的東西全部講出來,這樣也不利于整個團隊的相互學習和提高。
Reviewer的態度:它們對Code Review的態度很大程度上決定了Code Review的效果。常見以下幾種情況:
漠不關心:這種態度的來源主要是覺得代碼不是自己寫的,也不用負什么責任,對代碼走查的實際含義理解不清。想糊弄過去湊個人數結束。
藐視別人的代碼:這種心態長見于團隊中技術水平較高的成員中,在別人講解代碼的時候總覺得這個功能很容易實現,自己知道不用聽別人講了。這種人缺乏對團隊的責任感,和對團隊成員成果的尊重。
批評者:這類人對Code Review的目的是什么認識不清,總以為代碼走查就是找別人的錯,吊難別人。這種容易忽視別人代碼設計中的優點。做為程序員每個人都有自負的一面,這樣在Code Review時常常會出現Code Review就是找別人錯誤的錯誤認識。
Code Review 的形式:
Code Review做為當前常見的一種代碼質量和團隊技術交流的手段常見以下幾種形式:
Peer Review:這種形式是從結對編程中抽象出來的簡化版。主要由兩個人完成代碼走查工作,一個是代碼的編寫者,一個是對代碼的查看者。先由代碼編寫者向代碼走查者對代碼進行簡單的講解,然后由代碼查看者提出代碼需要改進的地方。之后由編寫者修改代碼。
Peers Review:這種形式是上面Peer Review的一個進化版增加了代碼查看者的數量,通過引入更多的眼睛來更有效的發現代碼存在的問題,同時使更多的人了解某一功能的解決方法,也擴大了對該功能的解決方法的討論的范圍。
分角色的多對一Code Review:和Peers Review不同的地方在于對Peers進行了簡單的分工,一般分為這樣幾個角色:Author,moderator,Recorder,Other reviewers。由Author準備Code Review時所需的材料并對材料進行簡單的講解,同時由moderator檢查所要Code Review的材料是否有效,同時決定代碼走查時的一個整體的走勢例如不能讓會議陷入漫無目的的討論中去,同時在代碼走查后負責檢查對代碼走查成果的修改工作是否到位。Recorder記錄代碼走查過程中發現的問題
以上三種形式,其中前兩種形式由于查看者的角色沒有細分,在Code Review的時候容易流于形式,從而使Code Review的效果大大折扣,但上面的形式也有好處,它們都更開發更利于交流。第三種形式是個人最好的一種形式,將在一下篇文章中詳細介紹這一形式。
?
CodeReview(3) --- 責任制
許多年前農村土地承包責任制的出現,使之大農民的角色發生了根本性的改變,從而迎來了糧食產量和農民很生活的巨大改善。同時在CodeRivew 這一個群體活動中,讓其有效運行起來一個最有效的方法就是分角色同時對某一角色賦予一定的責任。下面就對在我們團體中分角色的Code Review及其流程進行一個簡單的講解,同時也想和廣大軟件同仁們一起交流一下關于CodeReview的一些觀點和看法。因為是本公司的方法所以也會 有不足之處,歡迎討論。
一、Code Review 角色分類
??? 1.Author:被Review對象的作者。
??? 2.moderator:一般由團隊中開發經驗豐富的人擔任。
??? 3.Recorder:主要用于記錄在整個代碼Review中情況。
??? 4.Reader (may be the same person as Author or leader)
??? 5.Other reviewers:團隊中的其它成員,但是一般不要人太多,因為對于一個討論會議一來說一般要將參加會議的人控制在7人以內為最佳,這樣這個會議才是可控的。
??? 以上這些角色的職能會在Code Review中的不階段而發生變化。
?
二、Code Review的流程及其角色在不同階段的任務
上圖顯示了整個Code Review活動流程情況,一般在一個CodeReview活動會中Planning,Preparation,Meeting,Rework&Verfication是必須的,而 Overview階段會隨著Review對象的不同而不同,對于一些Review工作大量的活動這個階段是必須的,下面將詳細描述每個階段的任務,以及各 個角色在相對應階段的責任。
1.Planning:
這個階段主要是對各個角色人員的確定以及確定所Review的對象是否已經達到能夠被Review的階段,這樣以防止代碼在仍有很大 問題的情況下進行Review而導致Review的整體效率太低。還有對整個Review過程所以經歷的時間段有一個大體的劃分。在這一階段首先由Author確定誰來當本次Review的moderator(一般moderator只能從團隊中有限的幾個人內挑選,并不是每個人都可以充當這個角色的。)然后再邀請別人充當本次Review的Recoder,Other reviewers;
這個階段各個角色的主要任務是:
Author:對整個Review過程制定計劃,確定參加這次Rewview人員,為這些成員分發要Review的材料。
moderator:對整個要Review的對象進行分析查看是否達到能夠開始Code Review的要求。
2.Overview:
對于大量的東西要Review的項目,或者大部分參與Review的人對要Review的東西都不是很熟悉的情況下。由Author開招開一個簡短的站會整體解決一下所要Review的東西。
3.Preparation:
在這個階段,所有參與的reviewers對所以review的東西各自進行走讀,然后記錄并提交發現的問題,然后由Author和 moderator共同對reviewers所發現的問題進行匯總,分類,甄別。之后根據匯總上來的問題來進一步判斷是否適合招開Review會議。如果 匯總上來的問題比較多,比較嚴重則說明所要Reivew的文件尚未真正達到要求,則取消本次活動。由Author重新開發。如果發現的問題不是很多,則按 時招開Review Meeting.
?
這個階段各個角色的主要任務是:
reviewers:對所要Review的對象各自先進行走讀,然后提交各自發現的問題。
moderator和Author:對reviewers提交上來的問題進行匯總總結查看是否符合Review的條件。
4.meeting:
meeting做為整個review的核心和關鍵環節其主要任務是首先由Author主持對匯總上來的問題,逐個的分析然后給出自己的判斷,是接受reviewers還是不接受reviewers提出的問題。對于有分歧的問題進行討論,如果還有分歧則由moderator決定這個問題是否要改怎么 改。在將所有匯總上來的問題分析完后,再由Author帶著所有reviewers對代碼進行走讀。然后進一步分析和討論代碼中的問題。
?
這個階段各個角色的主要任務是:
Author:逐個分析匯總上來的問題,并給出自己的分析。帶領所有reviewers對代碼進行走讀;
moderator:分析判斷Author對問題的分析判斷是否合理,在關鍵時刻給出分歧問題的處理意見;
reviewers:討論分析之前提出的問題,對代碼進行集體的重新走讀,以發現更多的問題;
Recorder:對整個Code Review進行記錄,包括發現的問題以及問題的整改意見。
?
5.Rework&Verification:
這個階段主要是Author對整個Review過程提出的問題進行整改,然后提交由moderator對整個整改的情況進行評估。
總結:
通過對Code Review中的成員進行角色分工,從而賦予他們一定的職責,這樣就能很好的提高他們的責任感從而大大提高代碼走查的效率。
Const 重載解析
書上和網上在很多地方都對const 的重載做了一些解釋,但感覺都不是很詳細。還有很多同學在不同的地方發問關于const重載的問題,這里我又重新看了一下,做了一個簡單的分析也可能有不對的地方,歡迎討論。
所 謂重載,是指允許存在多個同名函數,而這些函數的參數表不同,即函數名相同但函數的簽名不同。重載并不是面向對象編程的特有屬性,這是因為重載是在編譯階段實現的,編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然后這些同名函數就成了不同的函數(這一點稍后有例子)。了
?
?Const 參數重載解析:
?
關于const 重載幾乎在所有c++的書中者提到過但大部分只是一句話,例如在《C++ primer》一書中這樣描述:“可基于函數的引用形參是指向 const 對象還是指向非 const 對象,實現函數重載。將引用形參定義為 const 來重載函數是合法的,因為編譯器可以根據實參是否為 const 確定調用哪一個函數。”
但是這一段描述并沒有給出引用、指針和值傳遞前加const的實質區別是什么。在用非const的指針,引用和值均可轉化為const的。這一點沒有太多可說明的東東。
對于函數值傳遞的情況,因為參數傳遞是通過復制實參創建一個臨時變量傳遞進函數的,函數內只能改變臨時變量,但無法改變實參。則這個時候無論加不加 const對實參不會產生任何影響。但是在引用或指針傳遞函數調用中,因為傳進去的是一個引用或指針,這樣函數內部可以改變引用或指針所指向的變量,這時 const 才是實實在在地保護了實參所指向的變量。因為在編譯階段編譯器對調用函數的選擇是根據實參進行的,所以,只有引用傳遞和指針傳遞可以用是否加const來 重載。
下面給出一個例子可能就更明白了:
?
C++ 代碼
?1 #include<iostream>
?2
?3?class A{
?4?public:
?5????A();
?6????int foo(int *test);
?7????int foo(const int *test);
?8};
?9A::A(){
10 }
11 ?int A::foo(int *test){
12 ????std::cout << *test << " A::foo(int *test)" <<std::endl;
13 ????return 1;
14 }
15 ?int A::foo(const int *test){
16 ????std::cout << *test << " A::foo(const int *test)" <<std::endl;
17 ????return 1;
18 }
19 ?int main()
20 {
21 ????const int b =5;
22 ????int c = 3;
23 ????A a;
24 ????a.foo(&b);
25 ????a.foo(&c);
26 ????return 1;
27 }
28 ?
復制代碼
?
?
輸出:
?
5 A::foo(const int *test)
3 A::foo(int *test)
?
?
那么編譯器又是怎樣工作的,通過g++ -S選項將匯編代碼生成出來,通過AT&T匯編代碼可以看出一些端倪來(之所以用AT&T匯編是因為VS生成的中間代碼實在是讓人頭暈):
?
代碼
? 1 .file??? "overload.cpp"
? 2????.section???.ctors,"aw",@progbits
? 3????.align 4
? 4????.long??? _GLOBAL__I__ZN1AC2Ev
? 5????.text
? 6????.align 2
? 7.globl _ZN1AC2Ev
? 8????.type??? _ZN1AC2Ev, @function
? 9?_ZN1AC2Ev:
?10.LFB1399:
?11????pushl??? %ebp
?12.LCFI0:
?13????movl??? %esp, %ebp
?14.LCFI1:
?15????popl??? %ebp
?16????ret
?17.LFE1399:
?18????.size??? _ZN1AC2Ev, .-_ZN1AC2Ev
?19.globl __gxx_personality_v0
?20????.align 2
?21.globl _ZN1AC1Ev
?22????.type??? _ZN1AC1Ev, @function
?23?_ZN1AC1Ev:
?24.LFB1400:
?25????pushl??? %ebp
?26.LCFI2:
?27????movl??? %esp, %ebp
?28.LCFI3:
?29????popl??? %ebp
?30????ret
?31.LFE1400:
?32????.size??? _ZN1AC1Ev, .-_ZN1AC1Ev
?33????.align 2
?34????.type??? _Z41__static_initialization_and_destruction_0ii,@function
?35?_Z41__static_initialization_and_destruction_0ii:
?36.LFB1411:
?37????pushl??? %ebp
?38.LCFI4:
?39????movl??? %esp, %ebp
?40.LCFI5:
?41????subl??? $24, %esp
?42.LCFI6:
?43????movl??? %eax, -4(%ebp)
?44????movl??? %edx, -8(%ebp)
?45????cmpl??? $1, -4(%ebp)
?46????jne??? .L9
?47????cmpl??? $65535, -8(%ebp)
?48????jne??? .L9
?49????movl??? $_ZSt8__ioinit, (%esp)
?50????call??? _ZNSt8ios_base4InitC1Ev
?51????movl??? $__dso_handle, 8(%esp)
?52????movl??? $0, 4(%esp)
?53????movl??? $__tcf_0, (%esp)
?54????call??? __cxa_atexit
?55.L9:
?56????leave
?57????ret
?58.LFE1411:
?59????.size???_Z41__static_initialization_and_destruction_0ii,.-_Z41__static_initialization_and_destruction_0ii
?60????.align 2
?61????.type??? _GLOBAL__I__ZN1AC2Ev, @function
?62?_GLOBAL__I__ZN1AC2Ev:
?63.LFB1413:
?64????pushl??? %ebp
?65.LCFI7:
?66????movl??? %esp, %ebp
?67.LCFI8:
?68????subl??? $8, %esp
?69.LCFI9:
?70????movl??? $65535, %edx
?71????movl??? $1, %eax
?72????call???_Z41__static_initialization_and_destruction_0ii
?73????leave
?74????ret
?75.LFE1413:
?76????.size??? _GLOBAL__I__ZN1AC2Ev,.-_GLOBAL__I__ZN1AC2Ev
?77????.align 2
?78????.type??? __tcf_0, @function
?79?__tcf_0:
?80.LFB1412:
?81????pushl??? %ebp
?82.LCFI10:
?83????movl??? %esp, %ebp
?84.LCFI11:
?85????subl??? $8, %esp
?86.LCFI12:
?87????movl??? $_ZSt8__ioinit, (%esp)
?88????call??? _ZNSt8ios_base4InitD1Ev
?89????leave
?90????ret
?91.LFE1412:
?92????.size??? __tcf_0, .-__tcf_0
?93????.section???.rodata
?94.LC0:
?95????.string???" A::foo(const int *test)"
?96????.text
?97????.align 2
?98.globl _ZN1A3fooEPKi
?99????.type??? _ZN1A3fooEPKi, @function
100 ?_ZN1A3fooEPKi:
101 .LFB1402:
102 ????pushl???%ebp
103 .LCFI13:
104 ????movl???%esp, %ebp
105 .LCFI14:
106 ????subl???$8,%esp
107 .LCFI15:
108 ????movl???12(%ebp),%eax
109 ????movl???(%eax), %eax
110 ????movl???%eax, 4(%esp)
111 ????movl???$_ZSt4cout, (%esp)
112 ????call??? _ZNSolsEi
113 ????movl???$.LC0, 4(%esp)
114 ????movl???%eax, (%esp)
115 ????call???_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
116 ????movl???$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
117 ????movl???%eax, (%esp)
118 ????call? ??_ZNSolsEPFRSoS_E
119 ????movl???$1,%eax
120 ????leave
121 ????ret
122 .LFE1402:
123 ????.size???_ZN1A3fooEPKi, .-_ZN1A3fooEPKi
124 ????.section???.rodata
125 .LC1:
126 ????.string???" A::foo(int *test)"
127 ????.text
128 ????.align 2
129 .globl_ZN1A3fooEPi
130 ????.type???_ZN1A3fooEPi, @function
131 ?_ZN1A3fooEPi:
132 .LFB1401:
133 ????pushl???%ebp
134 .LCFI16:
135 ????movl???%esp, %ebp
136 .LCFI17:
137 ????subl???$8,%esp
138 .LCFI18:
139 ????movl???12(%ebp),%eax
140 ????movl???(%eax), %eax
141 ????movl???%eax, 4(%esp)
142 ????movl???$_ZSt4cout, (%esp)
143 ????call??? _ZNSolsEi
144 ????movl???$.LC1, 4(%esp)
145 ????movl???%eax, (%esp)
146 ????call???_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
147 ????movl???$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
148 ????movl???%eax, (%esp)
149 ????call??? _ZNSolsEPFRSoS_E
150 ????movl???$1,%eax
151 ????leave
152 ????ret
153 .LFE1401:
154 ????.size???_ZN1A3fooEPi, .-_ZN1A3fooEPi
155 ????.align 2
156 .globlmain
157 ????.type???main, @function
158 ?main:
159 .LFB1403:
160 ????leal???4(%esp),%ecx
161 .LCFI19:
162 ????andl???$-16,%esp
163 ????pushl???-4(%ecx)
164 .LCFI20:
165 ????pushl???%ebp
166 .LCFI21:
167 ????movl???%esp, %ebp
168 .LCFI22:
169 ????pushl???%ecx
170 .LCFI23:
171 ????subl???$36,%esp
172 .LCFI24:
173 ????movl???$5, -8(%ebp)
174 ????movl???$3, -12(%ebp)
175 ????leal???-13(%ebp),%eax
176 ????movl???%eax, (%esp)
177 ????call??? _ZN1AC1Ev
178 ????leal???-8(%ebp),%eax
179 ????movl???%eax, 4(%esp)
180 ????leal???-13(%ebp),%eax
181 ????movl???%eax, (%esp)
182 ????call??? _ZN1A3fooEPKi
183 ????leal???-12(%ebp),%eax
184 ????movl???%eax, 4(%esp)
185 ????leal???-13(%ebp),%eax
186 ????movl???%eax, (%esp)
187 ????call??? _ZN1A3fooEPi
188 ????movl???$1,%eax
189 ????addl???$36,%esp
190 ????popl???%ecx
191 ????popl???%ebp
192 ????leal???-4(%ecx),%esp
193 ????ret
194 .LFE1403:
195 ????.size???main, .-main
196 ????.local???_ZSt8__ioinit
197 ????.comm???_ZSt8__ioinit,1,1
198 ????.weakref???_Z20__gthrw_pthread_oncePiPFvvE,pthread_once
199 ????.weakref???_Z27__gthrw_pthread_getspecificj,pthread_getspecific
200 ????.weakref???_Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
201 ????.weakref???_Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
202 ????.weakref???_Z22__gthrw_pthread_cancelm,pthread_cancel
203 ????.weakref???_Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
204 ????.weakref???_Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
205 ????.weakref???_Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
206 ????.weakref???_Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
207 ????.weakref???_Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
208 ????.weakref???_Z26__gthrw_pthread_key_deletej,pthread_key_delete
209 ????.weakref???_Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
210 ????.weakref???_Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
211 ????.weakref???_Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
212 ????.section???.eh_frame,"a",@progbits
213 .Lframe1:
214 ????.long???.LECIE1-.LSCIE1
215 .LSCIE1:
216 ????.long???0x0
217 ????.byte???0x1
218 ????.string???"zP"
219 ????.uleb128 0x1
220 ????.sleb128 -4
221 ????.byte???0x8
222 ????.uleb128 0x5
223 ????.byte???0x0
224 ????.long???__gxx_personality_v0
225 ????.byte???0xc
226 ????.uleb128 0x4
227 ????.uleb128 0x4
228 ????.byte???0x88
229 ????.uleb128 0x1
230 ????.align 4
231 .LECIE1:
232 .LSFDE5:
233 ????.long???.LEFDE5-.LASFDE5
234 .LASFDE5:
235 ????.long???.LASFDE5-.Lframe1
236 ????.long???.LFB1411
237 ????.long???.LFE1411-.LFB1411
238 ????.uleb128 0x0
239 ????.byte???0x4
240 ????.long???.LCFI4-.LFB1411
241 ????.byte???0xe
242 ????.uleb128 0x8
243 ????.byte???0x85
244 ????.uleb128 0x2
245 ????.byte???0x4
246 ????.long???.LCFI5-.LCFI4
247 ????.byte???0xd
248 ????.uleb128 0x5
249 ????.align 4
250 .LEFDE5:
251 .LSFDE7:
252 ????.long???.LEFDE7-.LASFDE7
253 .LASFDE7:
254 ????.long???.LASFDE7-.Lframe1
255 ????.long???.LFB1413
256 ????.long???.LFE1413-.LFB1413
257 ????.uleb128 0x0
258 ????.byte???0x4
259 ????.long???.LCFI7-.LFB1413
260 ????.byte???0xe
261 ????.uleb128 0x8
262 ????.byte???0x85
263 ????.uleb128 0x2
264 ????.byte???0x4
265 ????.long???.LCFI8-.LCFI7
266 ????.byte???0xd
267 ????.uleb128 0x5
268 ????.align 4
269 .LEFDE7:
270 .LSFDE9:
271 ????.long???.LEFDE9-.LASFDE9
272 .LASFDE9:
273 ????.long???.LASFDE9-.Lframe1
274 ????.long???.LFB1412
275 ????.long???.LFE1412-.LFB1412
276 ????.uleb128 0x0
277 ????.byte???0x4
278 ????.long???.LCFI10-.LFB1412
279 ????.byte???0xe
280 ????.uleb128 0x8
281 ????.byte???0x85
282 ????.uleb128 0x2
283 ????.byte???0x4
284 ????.long???.LCFI11-.LCFI10
285 ????.byte???0xd
286 ????.uleb128 0x5
287 ????.align 4
288 .LEFDE9:
289 .LSFDE11:
290 ????.long???.LEFDE11-.LASFDE11
291 .LASFDE11:
292 ????.long???.LASFDE11-.Lframe1
293 ????.long???.LFB1402
294 ????.long???.LFE1402-.LFB1402
295 ????.uleb128 0x0
296 ????.byte???0x4
297 ????.long???.LCFI13-.LFB1402
298 ????.byte???0xe
299 ????.uleb128 0x8
300 ????.byte???0x85
301 ????.uleb128 0x2
302 ????.byte???0x4
303 ????.long???.LCFI14-.LCFI13
304 ????.byte???0xd
305 ????.uleb128 0x5
306 ????.align 4
307 .LEFDE11:
308 .LSFDE13:
309 ????.long???.LEFDE13-.LASFDE13
310 .LASFDE13:
311 ????.long???.LASFDE13-.Lframe1
312 ????.long???.LFB1401
313 ????.long???.LFE1401-.LFB1401
314 ????.uleb128 0x0
315 ????.byte???0x4
316 ????.long???.LCFI16-.LFB1401
317 ????.byte???0xe
318 ????.uleb128 0x8
319 ????.byte???0x85
320 ????.uleb128 0x2
321 ????.byte???0x4
322 ????.long???.LCFI17-.LCFI16
323 ????.byte ???0xd
324 ????.uleb128 0x5
325 ????.align 4
326 .LEFDE13:
327 .LSFDE15:
328 ????.long???.LEFDE15-.LASFDE15
329 .LASFDE15:
330 ????.long???.LASFDE15-.Lframe1
331 ????.long???.LFB1403
332 ????.long???.LFE1403-.LFB1403
333 ????.uleb128 0x0
334 ????.byte ???0x4
335 ????.long???.LCFI19-.LFB1403
336 ????.byte???0xc
337 ????.uleb128 0x1
338 ????.uleb128 0x0
339 ????.byte???0x9
340 ????.uleb128 0x4
341 ????.uleb128 0x1
342 ????.byte???0x4
343 ????.long???.LCFI20-.LCFI19
344 ????.byte???0xc
345 ????.uleb128 0x4
346 ????.uleb128 0x4
347 ????.byte???0x4
348 ????.long???.LCFI21-.LCFI20
349 ????.byte???0xe
350 ????.uleb128 0x8
351 ????.byte???0x85
352 ????.uleb128 0x2
353 ????.byte???0x4
354 ????.long???.LCFI22-.LCFI21
355 ????.byte???0xd
356 ????.uleb128 0x5
357 ????.byte???0x4
358 ????.long???.LCFI23-.LCFI22
359 ????.byte???0x84
360 ????.uleb128 0x3
361 ????.align 4
362 .LEFDE15:
363 ????.ident???"GCC: (GNU) 4.1.2 20070925 (RedHat 4.1.2-33)"
364 ????.section???.note.GNU-stack,"",@progbits
復制代碼
如上面的代碼函數:
?
int foo(int *test);和int foo(constint *test);分別被編譯器生成名為:_ZN1A3fooEPKi和_ZN1A3fooEPi(這兩個名字會因為編譯器的不同而不同,名字只是一個區分的 符號而已不用深究,只用知道重載的函數經過編譯器的處理函數名字已經發生了變化。所以對于后面的匯編和鏈接工作就不存在重載的問題了。)這里也同時說明對重載來說在編譯階段已經完成。
對于a.foo(&b);因為變量b有const修飾所以就調用了int foo(const int *test);對于a.foo(&c);調用int foo(int *test);因為這個是精確匹配的。但是如果沒有定義intfoo(const int *test);則在代碼24行會出現編譯錯誤。反過來如果沒有定義函數:int foo(int *test);如下:
?
代碼
?1 #include<iostream>
?2
?3?class A{
?4?public:
?5????A();
?6?//??? int foo(int *test);
?7???? int foo(const int *test);
?8};
?9A::A(){
10 }
11 ?/*int A::foo(int *test){
12 ????std::cout << *test << "A::foo(int *test)" <<std::endl;
13 ????return 1;
14 }
15 */
16 int A::foo(const int *test){
17 ????std::cout << *test << " A::foo(const int *test)" <<std::endl;
18 ????return 1;
19 }
20 int main()
21 {
22 ????const int b =5;
23 ????int c = 3;
24 ????A a;
25 ????a.foo(&b);
26 ????a.foo(&c);
27 ????return 1;
28 }
復制代碼
則輸出結果為:
?
?
1 5 A::foo(const int *test)
2 3 A::foo(const int *test)
?
原因c++ primer上講的很清楚:“We can use a nonconst object to initializer either a const or nonconst reference. However, initializing a const reference to anonconst object requires a conversion, whereas initializing a nonconst parameter is an exact match.”
?
?
const 成員函數重載的解析:
?
const 成員函數重載的解析和const參數重載解析的原理可以說是一樣的。之所以這樣說是因為const成員函數的解析可被看做是對函數this參數用const來修飾的過程。例如下面代碼:
?
代碼
?1 #include<iostream>
?2
?3class A{
?4public:
?5????A();
?6????int foo(int *test); //可看做:int foo(A *this,int *test);
?7 ????int foo(int *test) const;//可看做:int foo(const A *this,int *test);
?8 };
?9A::A(){
10 }
11 int A::foo(int *test){
12 ????std::cout << *test << "foo"<<std::endl;
13 ????return 1;
14 }
15 int A::foo(int *test) const {
16 ????std::cout << *test << "foo const"<<std::endl;
17 ????return 1;
18 }
19 int main()
20 {
21 ????int b = 5;
22 ????const A a;
23 ????a.foo(&b);
24 ????return 1;
25 }
26
復制代碼
生成匯編為:
代碼
? 1 ????.file???"overload1.cpp"
? 2????.section???.ctors,"aw",@progbits
? 3????.align 4
? 4????.long??? _GLOBAL__I__ZN1AC2Ev
? 5????.text
? 6????.align 2
? 7.globl _ZN1AC2Ev
? 8????.type??? _ZN1AC2Ev, @function
? 9_ZN1AC2Ev:
?10.LFB1399:
?11????pushl??? %ebp
?12.LCFI0:
?13????movl??? %esp, %ebp
?14.LCFI1:
?15????popl??? %ebp
?16????ret
?17.LFE1399:
?18????.size??? _ZN1AC2Ev, .-_ZN1AC2Ev
?19.globl __gxx_personality_v0
?20????.align 2
?21.globl _ZN1AC1Ev
?22????.type??? _ZN1AC1Ev, @function
?23_ZN1AC1Ev:
?24.LFB1400:
?25????pushl??? %ebp
?26.LCFI2:
?27????movl??? %esp, %ebp
?28.LCFI3:
?29????popl??? %ebp
?30????ret
?31.LFE1400:
?32????.size??? _ZN1AC1Ev, .-_ZN1AC1Ev
?33????.align 2
?34????.type???_Z41__static_initialization_and_destruction_0ii, @function
?35_Z41__static_initialization_and_destruction_0ii:
?36.LFB1411:
?37????pushl??? %ebp
?38.LCFI4:
?39????movl ???%esp, %ebp
?40.LCFI5:
?41????subl??? $24, %esp
?42.LCFI6:
?43????movl??? %eax, -4(%ebp)
?44????movl??? %edx, -8(%ebp)
?45????cmpl??? $1, -4(%ebp)
?46????jne??? .L9
?47????cmpl??? $65535, -8(%ebp)
?48????jne??? .L9
?49????movl??? $_ZSt8__ioinit, (%esp)
?50????call??? _ZNSt8ios_base4InitC1Ev
?51????movl??? $__dso_handle, 8(%esp)
?52????movl??? $0, 4(%esp)
?53????movl??? $__tcf_0, (%esp)
?54????call??? __cxa_atexit
?55.L9:
?56????leave
?57????ret
?58.LFE1411:
?59????.size? ??_Z41__static_initialization_and_destruction_0ii,.-_Z41__static_initialization_and_destruction_0ii
?60????.align 2
?61????.type??? _GLOBAL__I__ZN1AC2Ev, @function
?62_GLOBAL__I__ZN1AC2Ev:
?63.LFB1413:
?64????pushl??? %ebp
?65.LCFI7:
?66????movl?? ?%esp,%ebp
?67.LCFI8:
?68????subl??? $8, %esp
?69.LCFI9:
?70????movl??? $65535, %edx
?71????movl??? $1, %eax
?72????call???_Z41__static_initialization_and_destruction_0ii
?73????leave
?74????ret
?75.LFE1413:
?76????.size??? _GLOBAL__I__ZN1AC2Ev,.-_GLOBAL__I__ZN1AC2Ev
?77????.align 2
?78????.type??? __tcf_0, @function
?79__tcf_0:
?80.LFB1412:
?81????pushl??? %ebp
?82.LCFI10:
?83????movl??? %esp, %ebp
?84.LCFI11:
?85????subl??? $8, %esp
?86.LCFI12:
?87????movl??? $_ZSt8__ioinit, (%esp)
?88????call??? _ZNSt8ios_base4InitD1Ev
?89????leave
?90????ret
?91.LFE1412:
?92????.size??? __tcf_0, .-__tcf_0
?93????.section???.rodata
?94.LC0:
?95????.string???"foo const"
?96????.text
?97????.align 2
?98.globl _ZNK1A3fooEPi
?99????.type??? _ZNK1A3fooEPi, @function
100 _ZNK1A3fooEPi:
101 .LFB1402:
102 ????pushl???%ebp
103 .LCFI13:
104 ????movl???%esp, %ebp
105 .LCFI14:
106 ????subl???$8,%esp
107 .LCFI15:
108 ????movl???12(%ebp),%eax
109 ????movl???(%eax), %eax
110 ????movl???%eax, 4(%esp)
111 ????movl???$_ZSt4cout, (%esp)
112 ????call??? _ZNSolsEi
113 ????movl???$.LC0, 4(%esp)
114 ????movl???%eax, (%esp)
115 ????call???_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
116 ????movl???$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
117 ????movl???%eax, (%esp)
118 ????call??? _ZNSolsEPFRSoS_E
119 ????movl???$1,%eax
120 ????leave
121 ????ret
122 .LFE1402:
123 ????.size???_ZNK1A3fooEPi, .-_ZNK1A3fooEPi
124 ????.align 2
125 .globlmain
126 ????.type???main, @function
127 main:
128 .LFB1403:
129 ????leal???4(%esp),%ecx
130 .LCFI16:
131 ????andl???$-16,%esp
132 ????pushl???-4(%ecx)
133 .LCFI17:
134 ????pushl???%ebp
135 .LCFI18:
136 ????movl???%esp, %ebp
137 .LCFI19:
138 ????pushl???%ecx
139 .LCFI20:
140 ????subl???$36,%esp
141 .LCFI21:
142 ????movl???$5, -8(%ebp)
143 ????leal???-9(%ebp),%eax
144 ????movl???%eax, (%esp)
145 ????call??? _ZN1AC1Ev
146 ????leal???-8(%ebp),%eax
147 ????movl???%eax, 4(%esp)
148 ????leal???-9(%ebp),%eax
149 ????movl???%eax, (%esp)
150 ????call??? _ZNK1A3fooEPi
151 ????movl???$1,%eax
152 ????addl???$36,%esp
153 ????popl???%ecx
154 ????popl???%ebp
155 ????leal???-4(%ecx),%esp
156 ????ret
157 .LFE1403:
158 ????.size ???main, .-main
159 ????.section???.rodata
160 .LC1:
161 ????.string???"foo"
162 ????.text
163 ????.align 2
164 .globl_ZN1A3fooEPi
165 ????.type???_ZN1A3fooEPi, @function
166 _ZN1A3fooEPi:
167 .LFB1401:
168 ????pushl???%ebp
169 .LCFI22:
170 ????movl???%esp, %ebp
171 .LCFI23:
172 ????subl???$8,%esp
173 .LCFI24:
174 ????movl???12(%ebp),%eax
175 ????movl???(%eax), %eax
176 ????movl???%eax, 4(%esp)
177 ????movl???$_ZSt4cout, (%esp)
178 ????call??? _ZNSolsEi
179 ????movl???$.LC1, 4(%esp)
180 ????movl???%eax, (%esp)
181 ????call???_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
182 ????movl???$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
183 ????movl???%eax, (%esp)
184 ????call??? _ZNSolsEPFRSoS_E
185 ????movl???$1,%eax
186 ????leave
187 ????ret
188 .LFE1401:
189 ????.size???_ZN1A3fooEPi, .-_ZN1A3fooEPi
190 ????.local???_ZSt8__ioinit
191 ????.comm???_ZSt8__ioinit,1,1
192 ????.weakref???_Z20__gthrw_pthread_oncePiPFvvE,pthread_once
193 ????.weakref???_Z27__gthrw_pthread_getspecificj,pthread_getspecific
194 ????.weakref???_Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
195 ????.weakref???_Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
196 ????.weakref???_Z22__gthrw_pthread_cancelm,pthread_cancel
197 ????.weakref???_Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
198 ????.weakref???_Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
199 ????.weakref???_Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
200 ????.weakref???_Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
201 ????.weakref???_Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
202 ????.weakref???_Z26__gthrw_pthread_key_deletej,pthread_key_delete
203 ????.weakref???_Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
204 ????.weakref???_Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
205 ????.weakref???_Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
206 ????.section???.eh_frame,"a",@progbits
207 .Lframe1:
208 ????.long???.LECIE1-.LSCIE1
209 .LSCIE1:
210 ????.long???0x0
211 ????.byte???0x1
212 ????.string???"zP"
213 ????.uleb128 0x1
214 ????.sleb128 -4
215 ????.byte???0x8
216 ????.uleb128 0x5
217 ????.byte???0x0
218 ????.long???__gxx_personality_v0
219 ????.byte???0xc
220 ????.uleb128 0x4
221 ????.uleb128 0x4
222 ????.byte???0x88
223 ????.uleb128 0x1
224 ????.align 4
225 .LECIE1:
226 .LSFDE5:
227 ????.long???.LEFDE5-.LASFDE5
228 .LASFDE5:
229 ????.long???.LASFDE5-.Lframe1
230 ????.long???.LFB1411
231 ????.long???.LFE1411-.LFB1411
232 ????.uleb128 0x0
233 ????.byte???0x4
234 ????.long???.LCFI4-.LFB1411
235 ????.byte???0xe
236 ????.uleb128 0x8
237 ????.byte???0x85
238 ????.uleb128 0x2
239 ????.byte???0x4
240 ????.long???.LCFI5-.LCFI4
241 ????.byte???0xd
242 ????.uleb128 0x5
243 ????.align 4
244 .LEFDE5:
245 .LSFDE7:
246 ????.long???.LEFDE7-.LASFDE7
247 .LASFDE7:
248 ????.long???.LASFDE7-.Lframe1
249 ????.long???.LFB1413
250 ????.long???.LFE1413-.LFB1413
251 ????.uleb128 0x0
252 ????.byte???0x4
253 ????.long???.LCFI7-.LFB1413
254 ????.byte???0xe
255 ????.uleb128 0x8
256 ????.byte???0x85
257 ????.uleb128 0x2
258 ????.byte???0x4
259 ????.long???.LCFI8-.LCFI7
260 ????.byte???0xd
261 ????.uleb128 0x5
262 ????.align 4
263 .LEFDE7:
264 .LSFDE9:
265 ????.long???.LEFDE9-.LASFDE9
266 .LASFDE9:
267 ????.long???.LASFDE9-.Lframe1
268 ????.long???.LFB1412
269 ????.long???.LFE1412-.LFB1412
270 ????.uleb128 0x0
271 ????.byte???0x4
272 ????.long???.LCFI10-.LFB1412
273 ????.byte???0xe
274 ????.uleb128 0x8
275 ????.byte???0x85
276 ????.uleb128 0x2
277 ????.byte???0x4
278 ????.long???.LCFI11-.LCFI10
279 ????.byte???0xd
280 ????.uleb128 0x5
281 ????.align 4
282 .LEFDE9:
283 .LSFDE11:
284 ????.long???.LEFDE11-.LASFDE11
285 .LASFDE11:
286 ????.long???.LASFDE11-.Lframe1
287 ????.long???.LFB1402
288 ????.long???.LFE1402-.LFB1402
289 ????.uleb128 0x0
290 ????.byte???0x4
291 ????.long???.LCFI13-.LFB1402
292 ????.byte???0xe
293 ????.uleb128 0x8
294 ????.byte???0x85
295 ????.uleb128 0x2
296 ????.byte???0x4
297 ????.long???.LCFI14-.LCFI13
298 ????.byte???0xd
299 ????.uleb128 0x5
300 ????.align 4
301 .LEFDE11:
302 .LSFDE13:
303 ????.long???.LEFDE13-.LASFDE13
304 .LASFDE13:
305 ????.long???.LASFDE13-.Lframe1
306 ????.long???.LFB1403
307 ????.long???.LFE1403-.LFB1403
308 ????.uleb128 0x0
309 ????.byte???0x4
310 ????.long???.LCFI16-.LFB1403
311 ????.byte???0xc
312 ????.uleb128 0x1
313 ????.uleb128 0x0
314 ????.byte???0x9
315 ????.uleb128 0x4
316 ????.uleb128 0x1
317 ????.byte???0x4
318 ????.long???.LCFI17-.LCFI16
319 ????.byte???0xc
320 ????.uleb128 0x4
321 ????.uleb128 0x4
322 ????.byte???0x4
323 ????.long???.LCFI18-.LCFI17
324 ????.byte???0xe
325 ????.uleb128 0x8
326 ????.byte???0x85
327 ????.uleb128 0x2
328 ????.byte???0x4
329 ????.long???.LCFI19-.LCFI18
330 ????.byte???0xd
331 ????.uleb128 0x5
332 ????.byte???0x4
333 ????.long???.LCFI20-.LCFI19
334 ????.byte???0x84
335 ????.uleb128 0x3
336 ????.align 4
337 .LEFDE13:
338 .LSFDE15:
339 ????.long???.LEFDE15-.LASFDE15
340 .LASFDE15:
341 ????.long???.LASFDE15-.Lframe1
342 ????.long???.LFB1401
343 ????.long???.LFE1401-.LFB1401
344 ????.uleb128 0x0
345 ????.byte???0x4
346 ????.long???.LCFI22-.LFB1401
347 ????.byte???0xe
348 ????.uleb128 0x8
349 ????.byte???0x85
350 ????.uleb128 0x2
351 ????.byte???0x4
352 ????.long???.LCFI23-.LCFI22
353 ????.byte???0xd
354 ????.uleb128 0x5
355 ????.align 4
356 .LEFDE15:
357 ????.ident???"GCC: (GNU) 4.1.2 20070925 (RedHat 4.1.2-33)"
358 ????.section???.note.GNU-stack,"",@progbits
359
復制代碼
上面可以看到編譯階段的調用也是通過對重載函數的別名來實現的。
總結:
1.const重載主要是通過能否對傳入的參數進行修改為判斷的。
2.const參數重載和const函數重載機制都是一樣的,因為對于const 函數重載可看做是對隱含的指針this的參數重載。
3.重載是在編譯階段已經完成,對于匯編和鏈接來說透明的。
?