这是半年前作的工作,T264初期开发设计主要针对X86结构,适合Window/linux两个系统,同时还有DM642的工程文件,实现移植却未作优化,运行起来超级慢,release版本也只有5fps(大概,即不太清了),qcif,当然其中也有因为文件传输导致时延(通过usb,没有将视频输入/输出文件保存SDRAM中)。
这里将T264便转换成纯C代码,适合于Window/Linux等系统,适合于ARM/Xscale/X86/DM642等系统构架 ,在Motorola的MX1和PXA255构架(linux系统)中都以验证ok。后期也进行了一些算法优化(插值、零块检测等)和指令集优化(ARM/Thumb指令)。
T264已经停止更新,而且编码性能欠佳(详见Peter李的三大编码器评测),所以基于T264开发H.264已经有些不切实际,而且有更好的选择——X264(基于intel的IPP库,MPlayer/FFMPEG开源视频编解码器!)不过基于一个较快速的纯C平台(相对于H.264的JM也是纯C),还是有许多可以学习和应用!
1. 在文件T264.c头,#define CHIP_DM642,因为DM642的编成语言基本用c,在结构上回避mmx指令
2. 将显示函数、文件删除:删除display.c, display.h, dither.c, win.h, win.c, yuvrgb24.c文件
3. 注释#ifdef USE_DISPLAY的内容
4. 在各个文件中删除#include “sse2.h”,并删除文件sse2.h文件
5. 删除cpu.asm等汇编文件
6. 修改 t264enc.c文件中的T264_init_cpu(t)函数,删除该函数中
#
ifndef
CHIP_DM642
if (t->param.cpu & T264_CPU_MMX)
{
…………
}
if (t->param.cpu & T264_CPU_SSE)
{
……
}
if (t->param.cpu & T264_CPU_SSE2)
{
……
}
#endif
后期,向T264中嵌入ARM指令或者Thumb指令,须将上述4~6恢复、修改
7. 对portab.h文件修改。
a) 删除
#ifdef
CHIP_DM642
#define
int8_t char
………………
#define
DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) /
type name[(sizex)*(sizey)]
#define
DECLARE_ALIGNED_MATRIX_H(name,sizex,sizey,type,alignment) /
type name[(sizex)*(sizey)]
#define
DECLARE_ALIGNED2_MATRIX_H(name,sizex,sizey,type,alignment) /
type name[(sizex)][(sizey)]
#endif
ported to Ti_Dsp_DM642 By You_xiaoQuan HFUT
b) 对于移植到linux系统,需要修改以下内容
#ifdef
__GCC__
#include
<inttypes.h>
#define
ptr_t uint32_t
#if
defined(ARCH_IS_IA32)
#define
BSWAP(a) __asm__ ( "bswapl %0/n" : "=r" (a) : "0" (a) );
static __inline int64_t read_counter(void)
{
int64_t ts;
uint32_t ts1, ts2;
__asm__ __volatile__("rdtsc/n/t":"=a"(ts1), "=d"(ts2));
ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1);
return
ts;
}
#define
SWAP(type, x, y) { type* _tmp_; _tmp_ = x; x = y ; y = _tmp_;}
#define
CLIP1(x) (x & ~255) ? (-x >> 31) : x
#define
ABS(x) ((x) > 0 ? (x) : -(x))
#else
// ARCH_IS_IA32
#error
Please port BSWAP to other platform!
#endif
// ARCH_IS_IA32
#define
DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) /
type name[(sizex)*(sizey)] __attribute__((aligned(alignment)))
#define
DECLARE_ALIGNED_MATRIX_H DECLARE_ALIGNED_MATRIX
#define
DECLARE_ALIGNED2_MATRIX_H(name,sizex,sizey,type,alignment) /
type name[(sizex)][(sizey)] __attribute__((aligned(alignment)))
#endif
// __GCC__
i. 修改其中的
#define BSWAP(a)的宏定义,将原来的PC汇编指令改为C语言。
#define
BSWAP(a){uint32_t tmp1,tmp2,tmp3,tmp4; tmp1=0x000000ff&a; tmp2=0x0000ff00&a; tmp3=0x00ff0000&a;tmp4=0x0ff000000&a;a=((tmp4>>24)+(tmp3>>8)+(tmp2<<8)+(tmp1<<24));}(后期工作中,需要将其改为
ARM或Thumb指令)
ii.
#define
DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) /
type name[(sizex)*(sizey)] __attribute__((aligned(alignment)))
#define
DECLARE_ALIGNED_MATRIX_H DECLARE_ALIGNED_MATRIX
#define
DECLARE_ALIGNED2_MATRIX_H(name,sizex,sizey,type,alignment) /
type name[(sizex)][(sizey)] __attribute__((aligned(alignment)))
这是将文件中定义的数据表字(或字节)对齐,对准字寻址优于非对准字寻址。许多编译器,如
arm-elf-linux-gcc,不能识别
__attribute__((aligned(alignment)))属性
改为
#define
DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) type name[(sizex)*(sizey)]
#define
DECLARE_ALIGNED_MATRIX_H DECLARE_ALIGNED_MATRIX
#define
DECLARE_ALIGNED2_MATRIX_H(name,sizex,sizey,type,alignment) type name[(sizex)][(sizey)]
c) 对于移植到windows系统,需要修改以下内容
#if
defined(_MSC_VER)
#define
int8_t char
…………
#if
defined(ARCH_IS_IA32)
…………
#endif
#define
DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) /
__declspec(align(alignment)) type name[(sizex)*(sizey)]
#define
DECLARE_ALIGNED_MATRIX_H(name,sizex,sizey,type,alignment) /
__declspec(align(alignment)) type name[(sizex)*(sizey)]
#define
DECLARE_ALIGNED2_MATRIX_H(name,sizex,sizey,type,alignment) /
__declspec(align(alignment)) type name[(sizex)][(sizey)]
#endif
// _MSC_VER
方法与上(b)类似
8. 对部分宏定义的修改,去掉换行连接符“/”,将原本的多行变为1行
9. 对Block.c文件的
static const int8_t index[4][4][6] =
{
………… };
修改为
static
const int8_t index_abc[4][4][6] =
否则会产生重定义出错。
10.
对Linux的Makefile的修改
a) 修改
LIBS= -lm -lX11
–
lXext为修改
LIBS= -lm
b)
删除LIBDIR= /usr/X11R6/lib
c)
@$(CC) -o $(BIN) $(OBJ) $(LIBS) -L$(LIBDIR)
改为@$(CC) -o $(BIN) $(OBJ) $(LIBS)
d)
CC= $(shell which gcc)
改为CC= $(shell which arm-elf-linux-gcc)
e)
删除AS= $(shell which nasm)