在Linux下编译t264
时间:2007-03-31 来源:rockins
|
(陈云川 [email protected] UESTC,CD)
1. 关于t264
t264是一个遵循H.264视频编码标准的视频编解码器(video codec)。是的,目前最常见的H.264编解码器是x264。不过无论如何,本文要讲的是如何在Linux下编译t264的问题。对于x264,没什么好说的,因为网上有很多相关的文章已经说得非常清楚了。t264的问题在于,它的文档实在是太少了,而且代码组织得也不如x264好。但是,据说t264的效率很高——注意,仅仅是据说而已,我目前还没有实测过,主要是还没有找到标准测试序列(test sequence)。
2. 准备工作
首先当然是下载t264的源代码,t264的主页地址为:www.sourceforege.net/projects/t264。这里作者下载的是最新的t264-src-0.14.zip——实际上t264已经很久没有更新了。下载到Linux系统上之后,首先解压:
[root@cyc t264]# ls
t264-src-0.14.zip
[root@cyc t264]# unzip t264-src-0.14.zip
解压之后进入源代码顶层目录,如下所示:
[root@cyc t264]# cd avc-src-0.14/avc/
[root@cyc avc]# ls -F
build/ changelog.txt common/ decoder/ dshow/ encoder/ readme.txt
源代码集中在common/、decoder/、encoder/、dshow/这几个目录下面,在build/目录下面则包含了针对不同平台的构建文件——对于Linux,这里指的是makefile;对于Windows,这里指的是针对Visual Studio的solution文件。除了上述两种平台之外,t264已经被移植到了TI公司的一款DSP上——名字叫做DM642。事实上,作者从未见过这款叫做DM642的处理器,不过DM642也可能是某个评估板的内部代号。无论如何,姑且解释为在下孤陋寡闻罢了。在build/目录下可以看到有下面这样几个子目录,分别对应着不同的平台:
[root@cyc avc]# cd build/
[root@cyc build]# ls -F
linux/ TiDM642/ vc6/ vc71/
既然我们是要在Linux平台下编译,那么,理所当然地,我们进入到linux/目录下面。在该目录下面存在着三个文件:dependencies中存放的是各个源文件之间的依赖关系,makefile不用说,自然是管理整个项目的make文件了,TAGS中存放着ctags程序生成的tag标记。解释一下什么是tag:如果读者使用过windows下的sourceinsight软件的话,一定会被sourceinsight强大的源代码分析能力、定位能力所折服。而在诸如vim、emacs这样的文本编辑器中,为了能够定位源程序中的变量或者对象,需要先通过ctags(适用于vim)或者etags(适用于emacs)生成tag文件,然后才能在一大堆程序代码中自由地跳转。除了C和C++这两种最常见的编程语言之外,ctags和etags目前还支持众多其它的编程语言,比如python。实际上,tag不tag跟我们这里要做的事情没有多大关系,因此回到我们的正题。
[root@cyc build]# cd linux/
[root@cyc linux]# ls
dependencies makefile TAGS
3. 编译过程
如果直接编译的话,将会出现如下所示的错误(由于编译产生的输出很多,这里仅节选了出错的部分):
compiling object file "../obj/cabac.o" ...
In file included from ../../encoder/cabac.c:57:
../../common/cabac_engine.h:26:23: Bitstream.h: No such file or directory
In file included from ../../encoder/cabac.c:57:
../../common/cabac_engine.h:31: parse error before "bs_t"
../../common/cabac_engine.h:41: parse error before "bs_t"
../../encoder/cabac.c:1199: parse error before "bs_t"
../../encoder/cabac.c: In function `T264_macroblock_write_cabac':
../../encoder/cabac.c:1201: `t' undeclared (first use in this function)
../../encoder/cabac.c:1201: (Each undeclared identifier is reported only once
../../encoder/cabac.c:1201: for each function it appears in.)
../../encoder/cabac.c:1202: `s' undeclared (first use in this function)
make: *** [../obj/cabac.o] Error 1
从编译输出的信息来看,是因为在cabac_engine.h中包含了Bitstream.h,同时又没有找到这个头文件,从而导致了后续的多个变量都出现了未定义错误。可恶的是,作者使用find命令在整个源代码树中都没有找到Bitstream.h头文件,但是其中有一个文件叫bitstream.h。于是,作者怀疑是开发者的一个笔误,故将cabac_engine.h中原来的include宏:
#include "Bitstream.h"
改成了:
#include "bitstream.h"
再次编译,出现新的错误:
compiling object file "../obj/cabac.o" ...
Assembler messages:
FATAL: can't create ../obj/cabac.o: No such file or directory
make: *** [../obj/cabac.o] Error 1
看样子,是因为不存在../obj/目录的缘故,这好办,我们自己建一个目录就可以了。作者实际的编译过程表明,除了需要../obj/目录之外,还需要一个../bin/目录,这里一并建好:
[root@cyc linux]# mkdir ../bin
[root@cyc linux]# mkdir ../obj
[root@cyc linux]# ls -F ..
bin/ linux/ obj/ TiDM642/ vc6/ vc71/
再次编译,又出现了一个新的错误,这次是找不到引用:
creating binary "../bin/t264"
../obj/yuvrgb24.o(.text+0x56): In function `ConvertYUVtoRGB':
: undefined reference to `clp'
../obj/yuvrgb24.o(.text+0x406): In function `init_dither_tab':
: undefined reference to `clp'
../obj/yuvrgb24.o(.text+0x40d): In function `init_dither_tab':
: undefined reference to `clp'
../obj/yuvrgb24.o(.text+0x412): In function `init_dither_tab':
: undefined reference to `clp1'
../obj/yuvrgb24.o(.text+0x421): In function `init_dither_tab':
: undefined reference to `clp'
../obj/yuvrgb24.o(.text+0x445): In function `init_dither_tab':
: undefined reference to `clp'
collect2: ld returned 1 exit status
make: *** [bin] Error 1
仔细检查源代码之后,作者发现在encoder/目录下的display.c文件中定义了clp和clp1:
unsigned char * clp = NULL;
unsigned char * clp1 = NULL;
但是两者是包围在一个条件编译预处理宏中的:
#ifdef USE_DISPLAY
…… // 这里定义了clp和clp1
#endif
而并没有任何地方定义了USE_DISPLAY这样一个宏,显然,这应该就是错误的根源所在。那么,怎么样修改比较好呢?作者是这样处理的:在makefile文件中,存在着下面这样一个语句:
CFLAGS= $(INCLUDE) -D__GCC__
将其修改为:
CFLAGS= $(INCLUDE) -D__GCC__ -DUSE_DISPLAY
然后,重新编译整个项目:
[root@cyc linux]# make clean && make
…… // 省略大量编译输出
creating binary "../bin/t264"
... done
update tag table
自此,编译完成。
4. TODO
目前暂时还没有对生成的t264程序进行测试,这是下一步要进行的工作。我将会根据对t264和x264的对比测试结果决定采用两者中的哪一个。
(本文PDF可到http://dormforce.net/Blog/rockins/archive/2007/03/31/13940.aspx下载)