`
weiyinchao88
  • 浏览: 1176024 次
文章分类
社区版块
存档分类
最新评论

ffmpeg mplayer x264 代码重点详解 详细分析

 
阅读更多

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参数.可以指定细节以决定视频音频质量和转换速率.具体的细节可以参看专业的技术文档.

7ffmpeg配置选项

[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编解码服务器?

设想一个简单的需求:

  1. 把其他编码的视频转换为指定码率的H.264;
  2. 在转换过程中做一些简单的处理(例如增删水印、字幕的处理、声音的处理等);
  3. 需要封装成指定的一种container格式,比如mp4或mkv。

ffmpeg完成此项工作的大概过程是:

  1. 识别文件格式,打开视频文件容器,得到video_stream;
  2. 使用libavcodec把video_stream解码成原始的frame数据;
  3. 在frame的基础上做“需求2”的处理;
  4. 编码成H.264格式;
  5. 存放到指定格式的容器中(mp4或者mkv)。

“过程1”应该是一个轻量操作,且对于现有视频格式速度应该很快(播放器看片的时候不可能先等上几秒分析一把格式再开始播放吧?)。

“过程2”需要把原有的视频编码解码并转为ffmpeg内部使用的格式,速度会比上第一步慢不少,但是应该也是可以接受的。当然在码率比较高的情况下也会非常缓慢(在Pentium4时代的机器上看1080p的高清视频很卡)。

“过程3”是需要对每一帧进行处理,那么这步是可高度并行化的应该可以放到GPU进行。

“过程4”一定是最慢的一个环节:H.264需要将图像分割成很多个宏块, 然后利用视频帧图像的帧内和帧间的相关性, 采用帧内预测或帧间预测的编码模式, 对各个宏块进行压缩。然后形成帧,组成为码流。整个过程复杂,但宏块儿的处理是可以高度并行化的操作,应该可以放到GPU进行。

“过程5”和“过程1”类似。

所以如果想用GPU加速以上的过程,那么把“过程4”和“过程2”的密集计算从CPU上转到GPU上,应该是可能的发力点。

如果要设计这个系统,软件自底层到上层有几点需要考虑:

  1. 如果显卡可以指定,应该是Nvidia。在Linux下有完善的开发运行环境,且同时支持CUDA和OpenCL;
  2. 如果选定Nvidia显卡,那么根据前文的分析,使用CUDA是更好的GPU计算架构。并且应该使用最新的CUDA 4.0版本,因为在多GPU上能更方便的开发,并且GPU直接访问内存方面也做出了改进(CUDA 4.0的新特性详细见这里)。
  3. 在决定了以上基础设施后,为了提高单机的处理能力程序应该用何种架构来编写?单进程多线程还是多进程单线程?

关键在于在程序里如何更好的调用CUDA:

  1. 单进程多线程方式
    • 每个线程进行一个视频的转换,每个线程在其线程内部直接使用CUDA;
    • 有单独的CUDA线程,其他线程当需要时通知此线程进行运算;
  2. 多进程单线程
    • 每个进程进行一个视频的转换,在其进程内部各自独立的使用CUDA;
    • 有单独的GPU进程,其他进程当需要进行GPU运算的时IPC通知此进程进行;

在我看来,2-1的方式是最简单直接的,可以直接基于ffmpeg来实现,只需单把可并行化的部分从CPU移到GPU。但是CUDA 4.0是否支持这样做?这样做效率是否最高?

硬件配置上也有以下的问题:

  1. 是否需要在一个Server上配置多块儿GPU?虽说CUDA 4.0已经声称对此有很好的支持,但是其是否能利用好?另外受限于硬件瓶颈的一些限制(CPU计算能力、内存速度、总线速度),配置几块儿GPU比较合适?
  2. 如果使用ffmpeg,那么在一台拥有16核的服务器上,理论可以同时启动16个ffmpeg进程(单线程运行)。加入GPU运算后单个视频处理速度的提高是一定的,但是否还有这么大的并行能力?以及单位时间段内的处理能力是否提升?
  3. 加入GPU后硬件成本的增加是否值得?与单独使用CPU的相比单位成本是否更低?选用哪款Nvidia显卡的性价比最高?
  4. 如何看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平台的编译版。

我们一般选择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和任何可以由ffmslavf打开的文件。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
3class A{
4public:
5A();
6int foo(int *test);
7int 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:
11pushl %ebp
12.LCFI0:
13movl %esp, %ebp
14.LCFI1:
15popl %ebp
16ret
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:
25pushl %ebp
26.LCFI2:
27movl %esp, %ebp
28.LCFI3:
29popl %ebp
30ret
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:
37pushl %ebp
38.LCFI4:
39movl %esp, %ebp
40.LCFI5:
41subl $24, %esp
42.LCFI6:
43movl %eax, -4(%ebp)
44movl %edx, -8(%ebp)
45cmpl $1, -4(%ebp)
46jne .L9
47cmpl $65535, -8(%ebp)
48jne .L9
49movl $_ZSt8__ioinit, (%esp)
50call _ZNSt8ios_base4InitC1Ev
51movl $__dso_handle, 8(%esp)
52movl $0, 4(%esp)
53movl $__tcf_0, (%esp)
54call __cxa_atexit
55.L9:
56leave
57ret
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:
64pushl %ebp
65.LCFI7:
66movl %esp, %ebp
67.LCFI8:
68subl $8, %esp
69.LCFI9:
70movl $65535, %edx
71movl $1, %eax
72call_Z41__static_initialization_and_destruction_0ii
73leave
74ret
75.LFE1413:
76.size _GLOBAL__I__ZN1AC2Ev,.-_GLOBAL__I__ZN1AC2Ev
77.align 2
78.type __tcf_0, @function
79__tcf_0:
80.LFB1412:
81pushl %ebp
82.LCFI10:
83movl %esp, %ebp
84.LCFI11:
85subl $8, %esp
86.LCFI12:
87movl $_ZSt8__ioinit, (%esp)
88call _ZNSt8ios_base4InitD1Ev
89leave
90ret
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 movl12(%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 movl12(%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 .typemain, @function
158 main:
159 .LFB1403:
160 leal4(%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 .sizemain, .-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 .long0x0
217 .byte0x1
218 .string"zP"
219 .uleb128 0x1
220 .sleb128 -4
221 .byte0x8
222 .uleb128 0x5
223 .byte0x0
224 .long__gxx_personality_v0
225 .byte0xc
226 .uleb128 0x4
227 .uleb128 0x4
228 .byte0x88
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 .byte0x4
240 .long.LCFI4-.LFB1411
241 .byte0xe
242 .uleb128 0x8
243 .byte0x85
244 .uleb128 0x2
245 .byte0x4
246 .long.LCFI5-.LCFI4
247 .byte0xd
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 .byte0x4
259 .long.LCFI7-.LFB1413
260 .byte0xe
261 .uleb128 0x8
262 .byte0x85
263 .uleb128 0x2
264 .byte0x4
265 .long.LCFI8-.LCFI7
266 .byte0xd
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 .byte0x4
278 .long.LCFI10-.LFB1412
279 .byte0xe
280 .uleb128 0x8
281 .byte0x85
282 .uleb128 0x2
283 .byte0x4
284 .long.LCFI11-.LCFI10
285 .byte0xd
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 .byte0x4
297 .long.LCFI13-.LFB1402
298 .byte0xe
299 .uleb128 0x8
300 .byte0x85
301 .uleb128 0x2
302 .byte0x4
303 .long.LCFI14-.LCFI13
304 .byte0xd
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 .byte0x4
316 .long.LCFI16-.LFB1401
317 .byte0xe
318 .uleb128 0x8
319 .byte0x85
320 .uleb128 0x2
321 .byte0x4
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 .byte0xc
337 .uleb128 0x1
338 .uleb128 0x0
339 .byte0x9
340 .uleb128 0x4
341 .uleb128 0x1
342 .byte0x4
343 .long.LCFI20-.LCFI19
344 .byte0xc
345 .uleb128 0x4
346 .uleb128 0x4
347 .byte0x4
348 .long.LCFI21-.LCFI20
349 .byte0xe
350 .uleb128 0x8
351 .byte0x85
352 .uleb128 0x2
353 .byte0x4
354 .long.LCFI22-.LCFI21
355 .byte0xd
356 .uleb128 0x5
357 .byte0x4
358 .long.LCFI23-.LCFI22
359 .byte0x84
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
3class A{
4public:
5A();
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:
5A();
6int 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:
11pushl %ebp
12.LCFI0:
13movl %esp, %ebp
14.LCFI1:
15popl %ebp
16ret
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:
25pushl %ebp
26.LCFI2:
27movl %esp, %ebp
28.LCFI3:
29popl %ebp
30ret
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:
37pushl %ebp
38.LCFI4:
39movl %esp, %ebp
40.LCFI5:
41subl $24, %esp
42.LCFI6:
43movl %eax, -4(%ebp)
44movl %edx, -8(%ebp)
45cmpl $1, -4(%ebp)
46jne .L9
47cmpl $65535, -8(%ebp)
48jne .L9
49movl $_ZSt8__ioinit, (%esp)
50call _ZNSt8ios_base4InitC1Ev
51movl $__dso_handle, 8(%esp)
52movl $0, 4(%esp)
53movl $__tcf_0, (%esp)
54call __cxa_atexit
55.L9:
56leave
57ret
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:
64pushl %ebp
65.LCFI7:
66movl %esp,%ebp
67.LCFI8:
68subl $8, %esp
69.LCFI9:
70movl $65535, %edx
71movl $1, %eax
72call_Z41__static_initialization_and_destruction_0ii
73leave
74ret
75.LFE1413:
76.size _GLOBAL__I__ZN1AC2Ev,.-_GLOBAL__I__ZN1AC2Ev
77.align 2
78.type __tcf_0, @function
79__tcf_0:
80.LFB1412:
81pushl %ebp
82.LCFI10:
83movl %esp, %ebp
84.LCFI11:
85subl $8, %esp
86.LCFI12:
87movl $_ZSt8__ioinit, (%esp)
88call _ZNSt8ios_base4InitD1Ev
89leave
90ret
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 movl12(%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 .typemain, @function
127 main:
128 .LFB1403:
129 leal4(%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 movl12(%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 .long0x0
211 .byte0x1
212 .string"zP"
213 .uleb128 0x1
214 .sleb128 -4
215 .byte0x8
216 .uleb128 0x5
217 .byte0x0
218 .long__gxx_personality_v0
219 .byte0xc
220 .uleb128 0x4
221 .uleb128 0x4
222 .byte0x88
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 .byte0x4
234 .long.LCFI4-.LFB1411
235 .byte0xe
236 .uleb128 0x8
237 .byte0x85
238 .uleb128 0x2
239 .byte0x4
240 .long.LCFI5-.LCFI4
241 .byte0xd
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 .byte0x4
253 .long.LCFI7-.LFB1413
254 .byte0xe
255 .uleb128 0x8
256 .byte0x85
257 .uleb128 0x2
258 .byte0x4
259 .long.LCFI8-.LCFI7
260 .byte0xd
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 .byte0x4
272 .long.LCFI10-.LFB1412
273 .byte0xe
274 .uleb128 0x8
275 .byte0x85
276 .uleb128 0x2
277 .byte0x4
278 .long.LCFI11-.LCFI10
279 .byte0xd
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 .byte0x4
291 .long.LCFI13-.LFB1402
292 .byte0xe
293 .uleb128 0x8
294 .byte0x85
295 .uleb128 0x2
296 .byte0x4
297 .long.LCFI14-.LCFI13
298 .byte0xd
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 .byte0x4
310 .long.LCFI16-.LFB1403
311 .byte0xc
312 .uleb128 0x1
313 .uleb128 0x0
314 .byte0x9
315 .uleb128 0x4
316 .uleb128 0x1
317 .byte0x4
318 .long.LCFI17-.LCFI16
319 .byte0xc
320 .uleb128 0x4
321 .uleb128 0x4
322 .byte0x4
323 .long.LCFI18-.LCFI17
324 .byte0xe
325 .uleb128 0x8
326 .byte0x85
327 .uleb128 0x2
328 .byte0x4
329 .long.LCFI19-.LCFI18
330 .byte0xd
331 .uleb128 0x5
332 .byte0x4
333 .long.LCFI20-.LCFI19
334 .byte0x84
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 .byte0x4
346 .long.LCFI22-.LFB1401
347 .byte0xe
348 .uleb128 0x8
349 .byte0x85
350 .uleb128 0x2
351 .byte0x4
352 .long.LCFI23-.LCFI22
353 .byte0xd
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.重载是在编译阶段已经完成,对于汇编和链接来说透明的。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics