关于X264的笔记整理

最近在x264的,焦头烂额,以下转载别人的资料,继续独自研究。

 

 

当初做x264优化时,一个人在摸索,一点点在改进,也记录下了一些东西,现在看来,有的相当琐碎,

而且也没多大价值,然而这也是自己当初的一种经历,以后工作了,估计就再不会接触H.264了,现在写下来,或许能对刚入门的人有点帮助吧。

 

2008-01-16 9:01
1.将所有的X264_LOG用LOG_printf代替,去掉common.c中的x264_log,log_default
2.所有的fprintf()即对文件的操作应该去掉
3.去掉信噪比的计算,因为在解码端也可得到
   在common.c中param->analyse.b_psnr = 0; //是否使用信噪比
4.设置set_en.c中的sps->b_vui = 0;表示vui信息不出现在码流中
sps->b_frame_mbs_only = 1;表示采用所有图像均帧编码
5.屏蔽掉:CAVLC_EN.C中的else if( i_mb_type == B_8x8 ),else if( i_mb_type

!= B_DIRECT ),else if( i_mb_type == B_DIRECT ),
   else if( i_mb_type == B_8x8 )
6.去掉common.h中的CHECKED_MALLOC中的if(!var)...(即检查分配内存成功与否)  
7.屏蔽掉ratecontrol_en.c中的x264_ratecontrol_new中的if( h-

>param.rc.i_rc_method == X264_RC_CRF)..和/* Load stat file and init 2pass

algo */
    if( h->param.rc.b_stat_read )...
8.去掉slicetype_decision_en.c中的if( h->param.rc.b_stat_read ) {...}和

void x264_slicetype_analyse( x264_t *h )函数,ratecontrol_en.c中的

x264_ratecontrol_slice_type函数
9.去掉ratecontrol_en.c中的update_vbv函数中的if( rcc->buffer_fill < 0 &&

!rcc->b_2pass )...,
       rate_estimate_qscale中的

if( rcc->b_2pass )..
       init_pass2(){...}函数
10.去掉encoder_en.c中的x264_validate_levels( h )语句和set_en.c中对应的函

数       

以上有一些修改涉及到检查参数的正确性,是因为在保证参数正确性的情况下这些语

句是可以去除的

2008-01-16 14:43

1.去掉if( h->param.rc.b_stat_read )开头的语句
2.去掉assert()语句
3.将CCS中的程序中的fprintf(...)全部去掉,(因为涉及到文件的操作,使用USB口传

输很耗时)
4.去掉exit(-1)之类报告程序错误的函数
5.去掉encoder_en中的#ifdef DEBUG_MB_TYPE...#endif之间的语句
6.去掉common.c中的x264_param_parse()函数
7.去掉analyse_en.c中的static const int i_mb_b_cost_table[19]类似的数组(B

帧用到的),以及以if( h->sh.i_type == SLICE_TYPE_B )...开头的语句


2008-01-16 19:33

1.去掉analyse_en.c中的x264_mb_analyse_inter_direct

(),x264_mb_analyse_inter_b16x16

(),x264_mb_analyse_inter_b8x8,x264_mb_analyse_inter_b16x8,x264_mb_analyse

_inter_b8x16()等五个函数,这五个函数是用来进行B帧帧间预测的,不需要用到
2.去掉macroblock.c中的if( h->sh.i_type == SLICE_TYPE_B && h-

>param.b_cabac )...
3.去掉所有以if( h->sh.i_type == SLICE_TYPE_B )..开头的语句
4.去掉以if( h->param.analyse.b_psnr )...开头计算PSNR的语句
5.将以for( i_list = 0; i_list < (h->sh.i_type == SLICE_TYPE_B ? 2 : 1 );

i_list++ )的循环去掉,因为不使用P帧只执行一次,不需循环
     但需加入i_list = 0;置初值
6将#ifdef _BS_H
#warning FIXME Multiple inclusion of bs.h
#else
#define _BS_H
改为:
#ifndef _BS_H
#define _BS_H
7.analyse_en.c中的x264_mb_analyse_b_rd(),refine_bidir()函数去掉
8.去掉cavlc_en.c中的uint8_t mb_type_b_to_golomb[3][9]和

sub_mb_type_b_to_golomb[13]数组
9.去掉common.c中的parse_enum(),parse_cqm(),atobool()函数


希望:将encoder_en.c中的if( h->param.rc.psz_stat_out )
        h->param.rc.psz_stat_out = strdup( h->param.rc.psz_stat_out );

这样就不需要自己定义的strdup函数了
       
2008-01-17 9:48
1.去掉encoder_en.c的x264_encoder_encode()函数中的两个没有用到的变

量:i_mb_i和i_mb_p(在CCS编译时的警告提示这两个变量定义但未被使用,
   其它有类似的警告也可以考虑去掉)
2.去掉frame.c中的x264_frame_new()函数中的以fail:标号开头的三句话(在程序中

不会调用)
去掉macroblock.c中的x264_macroblock_cache_init()函数中的以fail:标号开头

的两句话
3.pridect.c中的UNUNSED变量该如何处理?(CCS中警告说没有使用,但直接删除在VC

下会报错!)          
4.去掉所有以#ifdef HAVE_MMXEXT ...#endif的语句
5.去掉ratecontrol_en.c中的parse_zones相关的三处代码
6.去掉encoder_en.c中的x264_encoder_close()函数中的

x264_ratecontrol_summary( h )函数及在ratecontrol.c中的相应代码(因为在这个

函数中调用了if(rc->b_abr)...;
7.去掉ratecontrol_en.c中的与rate_estimate_qscale()和get_diff_limited_q()

有关的函数
8.去掉x264.c中的strtable_lookup()函数,与/* update status line (up to 1000

times per input file) */有关的语句
*******************
1.考虑将ratecontrol_en.h中的声明的函数在程序中被使用的地方全部替换!!!即删

掉ratecontrol_en.c文件,不使用码率控制
2.去掉以rc->b_abr,b->2pass判断的语句
*******************

2008-01-17 19:53
1.去掉ratecontrol_en.c中的get_qscale()和clip_qscale()函数
2.去掉encoder_en.c中的关于x264_psnr()的宏及调用它的函数(不计算信噪比)

ratecontrol_en.c中的调用:
1.
Searching for 'x264_ratecontrol_start'...
F:/H.264/youhua/x264Vc/encoder_en.c(1350):    x264_ratecontrol_start( h,

i_slice_type, h->fenc->i_qpplus1 );

2.Searching for 'x264_ratecontrol_new'...
F:/H.264/youhua/x264Vc/encoder_en.c(617):    if( x264_ratecontrol_new( h

) < 0 )

3.Searching for 'x264_ratecontrol_delete'...
F:/H.264/youhua/x264Vc/encoder_en.c(1842):    x264_ratecontrol_delete( h

);

4.Searching for 'x264_ratecontrol_threads_start'...
F:/H.264/youhua/x264Vc/encoder_en.c(1124):       

x264_ratecontrol_threads_start( h );
F:/H.264/youhua/x264Vc/encoder_en.c(1148):       

x264_ratecontrol_threads_start( h );

5.Searching for 'x264_ratecontrol_slice_type'...
F:/H.264/youhua/x264Vc/slicetype_decision_en.c(381):               

x264_ratecontrol_slice_type( h, h->frames.next[i]->i_frame );
(已经被去掉)2008-01-17 20:37

6.Searching for 'x264_ratecontrol_mb'...
F:/H.264/youhua/x264Vc/encoder_en.c(1074):           

x264_ratecontrol_mb(h, bs_pos(&h->out.bs) - mb_spos);

7.earching for 'x264_ratecontrol_qp'...
F:/H.264/youhua/x264Vc/analyse_en.c(1950):    x264_mb_analyse_init( h,

&analysis, x264_ratecontrol_qp( h ) );
F:/H.264/youhua/x264Vc/encoder_en.c(1351):    i_global_qp =

x264_ratecontrol_qp( h );

8.Searching for 'x264_ratecontrol_end'...
F:/H.264/youhua/x264Vc/encoder_en.c(1541):    x264_ratecontrol_end( h,

i_frame_size * 8 );

2008-01-19 9:17
1.修改x264.c中的Encode_frame()和Encode()函数,修改原来程序中的编码一帧,写

一帧到输出文件为编码所有的帧完成后再一次写入到输出文件中
(此处给存放输出文件的缓冲只分配了1M大小)


2008-01-20 17:23
1.在编译选项中添加-k,-mw,可以生成反馈文件信息(.asm)

2008-01-22 20:33
修改X264.C中的main函数,
为输入的文件分配一个缓冲,p_readYUV,5M大小.
先将YUV文件读入到这个缓冲中,然后在编码时每次读取YU的V分量只需要使用MEMCPY

从内存中复制对应的数据即可.
两天时间,终于快解决这个输入缓冲的问题!这样做仍然在CCS中仍然是将PC上的YUV

文件通过USB口读取到EVM的SDRAM中,速度仍然很慢,今后要是
能使用网络传输应该会快很多,但现在主要是作优化,只要与PC通信的这块能够不占

入编码时间就很好了.
主要代码如下:
/* raw 420 yuv file operation */
int open_file_yuv( char *psz_filename, hnd_t *p_handle, x264_param_t

*p_param )
{....
//获得文件的长度
fseek(h->fh,0,SEEK_END);
i_file_length =ftell(h->fh);
fseek(h->fh,0,SEEK_SET);

//读取YUV文件
fread(p_readYUV,1,i_file_length,h->fh);
...
}

int read_frame_yuv( x264_picture_t *p_pic, hnd_t handle, int i_frame )
{
    yuv_input_t *h = handle;

/* if( i_frame != h->next_frame )
        if( fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 /

2, SEEK_SET ) )
            return -1;*/
  
/*   if( fread( p_pic->img.plane[0], 1, h->width * h->height,

h->fh ) <= 0
            || fread( p_pic->img.plane[1], 1, h->width * h->height / 4,

h->fh ) <= 0
            || fread( p_pic->img.plane[2], 1, h->width * h->height / 4,

h->fh ) <= 0 )
      return -1;*/
//从内存中复制数据
   memcpy(p_pic->img.plane[0], p_readYUVBuffer , h->width *

h->height);    
   memcpy(p_pic->img.plane[1], p_readYUVBuffer+h->width * h

->height , h->width * h->height/ 4);
   memcpy(p_pic->img.plane[2], p_readYUVBuffer +h->width *

h->height+ h->width * h->height/ 4, h->width * h->height/ 4);
   p_readYUVBuffer=p_readYUVBuffer +h->width * h->height+ h

->width * h->height/ 4+ h->width * h->height/ 4;
  
  
   h->next_frame = i_frame+1;
  
   return 0;
}

在CCS中的char 换成uint8_t

2008-01-23 15:29
修改DSP/BIOS,将BIOS的对象分配到IRAM中,将BIOS需要的STACK分配在DDR2FORHEAP

中,
1.此时在p_readYUVBuffer=x264_malloc(0x500000);分配5M的输入缓冲时占了较长

时间(估计有10分钟了)
修改COMMON.C中的X264_malloc,将buf = (uint8_t *) malloc( i_size + 15 +

sizeof( void ** ) +
                   

sizeof( int ) );
   改成:buf=(uint8_t *)MEM_calloc(DDR2forHeap, i_size + 15 +

sizeof( void ** ) +
              sizeof( int ),0); (使用DSP/BIOS提供的MEM分配函数)
             
2008-01-24 21:01
1.下午将fread从CCS中读到的数据,用CCS的DATA->SAVE把对应的foreman01.yuv文件

保存为DATA格式的foreman01.dat,以后要作测试时,直接使用
DATA-->LOAD将其导入到SRAM中即可
2.调试时出现问题:在编码第一帧后又返回到了主函数,这样一直在重复编码一帧!不

知道是不是因为将main()和smain()函数放在同一个x264.c文件里面的
缘故?是不是main()函数必须单独作一个文件?
在log_printf.pjt工程里证明不是因为必须在一个文件里的问题         
3.以上出现程序跑飞的原因可能是因为TSK0的任务堆栈太小(默认是1024),在

DSP/BIOS里改成了(10000)
4.是在encoder_en.c中的x264_slice_write函数中又跑到主函数中去的  
可能是因为文件操作的原因?

2008-02-20 15:47
1.
关于用CCS的DATA->SAVE把对应的foreman01.yuv文件保存为DATA格式的

foreman01.dat,以后要作测试时,直接使用
DATA-->LOAD将其导入到SRAM中,在CCS中使用VIEW-MEMORY查看内存中的数的读的方

法:
如DAT文件如下
1651 1 85000010 0 11fb80
0xFFC9280A
0xFEFEFEF7
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xFEFEFEFE
0xE9FEFFFD
..........
..........
在SRAM中0x8500 0010存放第一个数0xFFC9280A,第二个数的0xFEFEFEF7的地址为

0x8500 0010 + 4*(2-1)=0x8500 0014,
第12个数0xE9FEFFFD的地址为0x8500 0010+4*(C-1)=0x8500 003C;
最后一个数(第1178496个数)的地址为 0x8500 0010 + 4*(11fb80-1)=0x8547 ee0c;

(1178496转换为十六进制为0x11fb80);
即第n个数的存放地址为0x8500 0010+4*(n(十六进制)-1);

2008-02-22 10:21
将所有的fseek换成lseek(http://bbs.lmtw.com/dv_rss.asp?

s=xhtml&boardid=20&id=118797)
仍不能解决问题!!!

2008-02-22 15:07
1.尝试方法:恢复1.17号的X264.C文件,即还是采用fopen,fread,从PC上读一帧编码

后再从PC上读另一帧,看是否正常
使用DATA-LOAD的备份文件为:复件 (4) x264.c
在使用DATA-LOAD的程序中似乎可以不需要open_file_yuv..
使用类似的程序在VC下可以正常编码..

2008-02-22 21:53
问题得到解决:将ccs中的macroblock.c用F:/H.264/youhua/x264Vc目录下的

macroblock.c文件替换,就可以正常编码了
可见当时对这两个文件没有同步更新!!!导致一个跨越年度的错误!!
但生成的文件有800多kb,

2008-02-25 16:27
将DSP/BIOS中的MEM重新分配,使p_writeBuffer与p_readBuffer不指向同一块内存,

生成的文件大为缩小,只有132KB,
但是编码30帧的速度仍然需时近5分钟

2008-02-26 19:56
使用BUILD OPTION:
-g -k -o3 -fr"$(Proj_dir)/Debug" -d"_DEBUG" -d"__X264__" -mw -mv6400+ --

mem_model:data=far
速度30帧大约需要1分钟

对于fps的计算仍未清楚,clock()两次运行同样的程序得到的时间竟然不同!


2008-02-27 21:20
仍然在研究使用何种方法来获得程序运行的时间,
clock()只有用load6x()时才较准确,
CLK_getltime()是推荐的用法,不过要引入中断
新建一个工作(在F:/DSP/CCS/CLK)专门用来测试CLK_getltime()的用法,发现:
1.只有用timer0时,定时器中断才能进入,
2.使用Profile菜单中的clock->view看时钟时,根据DSP/BIOS中的CLK manager中的

Specify input clock rate来,得到的clock不同,
默认这项是选中的,27MHZ时得到的cycle数比不选中时(594MHZ)时少的多,这可能也

是采用clock()不准确的原因

2008-02-28 9:05
跟昨天一样的程序,同样的DSP/BIOS配置,昨天可以用CLK_getltime()获取时间,今天

为什么就返回的是0了???

1.将dsp264_3.pjt的DSP/BIOS的CLK manager中选中为timer0
在x264.c的encode函数中将计算fps,需获得开始时间改为:
i_start=CLK_getltime();
i_end=CLK_getltime();
调试程序时测得i_start=15 ,i_end=55462 (单位ms),
fps=31(帧)/i_end-i_start=0.56(帧/秒) 与实际观测相近

2008-02-28 19:00
1.删除mdate.c及相关的X264_mdate()宏,使用CLK_getltime()获取时间
(删除common.h中的int64_t x264_mdate( void );
encoder_en.c中的#define TIMER_START( d ) /...宏,和encoder_en.c中的调用了

TIMER_START()和TIMER_STOP的宏的行(这在VC上可以成功))
2.变量存储类型调整:在VC中long和int 都是定义成32位,(见MSDN)而在CCS中long定

义成40位,因此将CCS中的long换成int
在VC中同步更新
4.去掉if __x264__..else语句
5.在x264.c中的encode函数中加入double fps,然而程序运行时却发现fps一直都是

未定义变量,
对x264.c去掉-O3编译选项,即可认出fps,可能是O3选项优化时将这句代码删掉

了...,若去掉O3选项,编码速度很慢!
将double fps设为全局变量,可以正常计算,

前两天在测试clock()和CLK_getltime(),今天晚上就在测试这个fps的计算了,期

间犯过将ms转换为s乘1000的低级错误...真是效率低!
2008-02-29 11:00
1.加入-pm和-pm op0和-pm op2 -pm -op3优化选项编译,结果程序又重复编译第一

帧了...
2.加入-pm -op1优化选项,出现错误:
    [Linking...] "C:/CCStudio_v3.3/C6000/cgtools/bin/cl6x" -@"Debug.lkf"

undefined                        first referenced
symbol                              in file
---------                        ----------------
_smain                           F://H.264//dsp264_3

//Debug//dsp264_3cfg.obj
>>   error: symbol referencing errors - './Debug/dsp264_3.out' not built
在int smain()函数前加入:#pragma FUNC_EXT_CALLED (smain);BUILD无错误,但仍

然程序重复编译第一帧


2008-03-01 10:23
1.使用
-k -o3 -fr"$(Proj_dir)/Debug" -d"_DEBUG" -mt -mw -mv6400+ --

mem_model:data=far选项,编码速度为0.60fps
2.-k -pm -op0 -o3 -fr"$(Proj_dir)/Debug" -d"_DEBUG" -mt -mw -mv6400+ --

mem_model:data=far    ...0.46fps,foreman01.264文件>157KB
昨天使用-pm -op0选项不成功可能是因为不能加上-g选项

2008-03-01 15:50
参考:F:/H.264/移植/g宋扬-基于TMS320DM642DSP的H_264编码器优化与设计.nh
1.项目级优化:使用-o3 -k -mt -mw

2008-03-02 11:05
1.参考F:/H.264/移植/gH_264视频编码技术研究及其在TI_DSPDM642上的实现.nh的

<<3.5.3节对X264帧间预测模式选择算法的改进>>
修改帧间预测算法,在X264VC中的analyse_en.c中修改,主要是屏蔽了void

x264_macroblock_analyse( x264_t *h )函数中
if( analysis.b_mbrd )
{
/* refine later */
}
else if( i_partition == D_16x16 )
{
// x264_me_refine_qpel( h, &analysis.l0.me16x16 );   与此类似

的1/4像素精度搜索
    i_cost = analysis.l0.me16x16.cost;
}

这段算法还是不能删除!因为这些就是在在选择了最优预测模式后的分像素精度搜索

2008-03-06 14:51
1.去掉VC版本中pixel.c中void x264_pixel_init()关于PSNR的计算:INIT( ssd,

),INIT( sad_x3, );在dsp264_3.pjt中作相应修改
2008-03-07 9:00
1.去掉VC...pixel.c中pixel_sa8d_wxh()...及与sa8d相关的语句,在CCS中亦作相应

修改


2008-03-12 10:43
根据CCS中函数结构和调用约定,对于x264_pixel_sad_16x16之类的
static int name( uint8_t *pix1, int i_stride_pix1, /
                 uint8_t *pix2, int i_stride_pix2 )函数,
在传递参数时前四个参数分别是A4,B4,A6,B6,
将这些函数形参先后顺序改为 static int name( uint8_t *pix1,uint8_t *pix2,
       int i_stride_pix1,int

i_stride_pix2 ) 似乎更利于CCS的并行运行.
因为对于pix1,pix2分别是参考宏块,分别采用A4,B4,作为寄存器调用,可以减少一次

T通道的使用(但可能会增加X的使用了)  
先在VC中更改形参的次序,以"h->pixf.sad"为关键字搜索,修改如下地方:
F:/H.264/youhua/x264Vc/me_en.c(52):    /*int cost = h->pixf.sad[i_pixel](

m->p_fenc[0], FENC_STRIDE,/
                   &p_fref[(my)*m->i_stride[0]+(mx)], m->i_stride[0] )/
             + BITS_MVD(mx,my);/*/
修改为:int cost = h->pixf.sad[i_pixel]( m->p_fenc[0],&p_fref[(my)*m-

>i_stride[0]+(mx)],/
      FENC_STRIDE, m->i_stride[0] )/
    + BITS_MVD(mx,my);/ 即交换第二个和第三个形参

的位置.以下修改类似            
          
F:/H.264/youhua/x264Vc/me_en.c(62):    int cost = h->pixf.sad[i_pixel](

m->p_fenc[0], FENC_STRIDE, src, stride ) /
F:/H.264/youhua/x264Vc/me_en.c(70):    h->pixf.sad_x3[i_pixel]( m-

>p_fenc[0],/
F:/H.264/youhua/x264Vc/me_en.c(83):    h->pixf.sad_x4[i_pixel]( m-

>p_fenc[0],/
F:/H.264/youhua/x264Vc/me_en.c(101):    h->pixf.sad_x4[i_pixel]( m-

>p_fenc[0],/
F:/H.264/youhua/x264Vc/me_en.c(468):            const int enc_dc = h-

>pixf.sad[i_pixel]( m->p_fenc[0], FENC_STRIDE, zero, 16 );
F:/H.264/youhua/x264Vc/me_en.c(544):    int cost = h->pixf.sad[i_pixel](

m->p_fenc[0], FENC_STRIDE, src, stride ) /
F:/H.264/youhua/x264Vc/me_en.c(622):        h->pixf.sad_x4[i_pixel]( m-

>p_fenc[0], src0, src1, src2, src3, stride, costs );

修改了:me_en.c中的#define COST_MV( mx, my )/,#define COST_MV_PRED( mx,

my ) /,
const int enc_dc = h->pixf.sad[i_pixel]( m->p_fenc[0], zero, FENC_STRIDE,

16 );                
#define COST_MV_SAD( mx, my ) /
和pixel.c中的static int name( uint8_t *pix1, uint8_t *pix2,   /
   int i_stride_pix1, int i_stride_pix2 )
   及SAD_x3和SAD_x4中的参数顺序
和pixel.h中,添加typedef int (*x264_pixel_sad_t) ( uint8_t *, uint8_t *,

int, int );
   及将x264_pixel_function_t结构体中的x264_pixel_cmp_t sad

[7];改为:x264_pixel_sad_t sad[7];
作以上修改后,release版速度只有8.94fps,不知是不是重启后速度会快些

以此修改dsp264_3中对应的文件,将原有文件作备份(后缀名后加08311)


2008-03-13 9:02
1.经昨日修改之后,在X264_PIXEL_sad_16x16线性汇编中的软件流水信息显示的是ii

= 3 Schedule found with 5 iterations in parallel
                                       .C中的...    

是ii = 4 Schedule found with 4 iterations in parallel
比未经修改的速度应该有提升,然而程序运行总出错:编译一帧后即停止运行
2.经昨日修改的VC今天重启电脑运行,速度可以达到15.74fps,因此昨日所作修改对

程序不会造成影响

2008-03-15 20:13
1.田晓东-基于TMS320DM642的H_264视频编码.kdh
4.4节,存储器的高度策略,有讲到分配的程序举例,和SAD16X8的线性汇


2008-03-16 9:50
1.g王澎-H_264视频编码器在DSP平台上的移植和优化.kdh
5.4.1节 短整型J无论是在精度还是范围上都能满足需求。经过测试,将全

局的预测模式,预测残差,直流、交流系数等频繁使用的变量,以及大部分的表,

都从整Iii}J改为短整Iii}J。经过编

2008-03-16 14:38
1.将CCS中bs.h,common.h等中的int类型的数据改为short,(函数返回类型的int不

变)
    改动前:far段:002dd248(Byte),.text     00040460,.const   00007631

,.cinit 00001484,
    改动后:.const    000064a9 ,其它无变化
2.彻底删除了csp.c文件。这个文件中有一段代码(plane_copy函数),我们的程序

仍然需要。所以在在frame.c文件中补充了i420_to_i420函数,它包括了plane_copy

函数的代码。   

2008-03-17 15:40
.far 002dd248(Byte)    2.86M
.text   0003f3e0    252.97K
.const 000064a9    25.16k
.bios 00004bc0    18.94k
.cinit 00001484     5.12k
.bss 00000378       0.87k
.switch 0000015c     0.34k
.cio    00000120    0.28k

2008-03-17 20:11

X264_PIXEL_SAD_16X16 C代码经过-o3优化后,执行43次,平均每次需12306个cycles


2008-03-19 8:58
在VC程序中存在,在CCS中应该可以修改的:所有的memcpy函数,memset
1.encoder_en.c中x264_encoder_open函数中分配当前帧缓冲..
2.set.c中的int换成short


2008-03-23 14:58(此次屏蔽用"///"和"/*/....*/")
去掉VC版x264.h中x264_param_t结构体中的

CPU,ithreads,vui,i_bframe,b_bframe_adaptive,i_bframe_bias,b_bframe_pyrami

d变量
2008-03-26 8:59
去掉VC版x264.h中x264_param_t结构体中的b_weighted_bipred,b_bidir_me和与

2pass相关的变量b_stat_write,psz_stat_out,b_stat_read,psz_stat_in
psz_rc_eq,f_qcompress,f_qblur,f_complexity_blur,zones,i_zones,psz_zones.
去掉b_cabac,i_cabac_init_idc
屏蔽掉x264_zone_t结构体定义
**对于句法元素中的定义的变量不能删掉,如x264_pps_t中的b_weighted_bipred,因

为它是要出现在码流中的

2008-03-26 14:52
去掉VC版本中common.h中的x264_cabac_t结构

2008-04-14 20:30
将上个月修改后的VC移植到CCS下,硬件时可以跑通,设置QP=32,-O3优

化,foreman.cif可达1.0fps,mother and daughter.cif 1.4fps.
经历近一个月的不知道从何处下手开始优化,现在找到工作步骤了,今天晚上运行软

件仿真,分析函数的代码大小,占用时间,CACHE命中,再按存储分配--项目优化等过程

来进行!
现在将程序移植到C64X+的SIMULATOR(需将DSP/BIOS中的CLK模块禁用/工程目

录:F:/H.264/dsp264yh_simulator),程序可以跟踪运行.初步得到了CODE SIZE的大

小,
发现int x264_me_refine_bidir( x264_t *h, x264_me_t *m0, x264_me_t *m1,

int i_weight ) 函数(me_en.c中)占用15572bytes,而这个函数并没有被运行到,
因此可以删除(均先在VC下删除,确认程序能正常运行后再在CCS下修改),减小所占代

码大小,删除此函数后,VC下生成的x264.exe由453KB变成433KB,
类似的,删除x264_me_refine_qpel_rd()函数(3720bytes),429KB,
根据x264_slicetype_mb_cost()占用3336bytes分析slicetype_decision_en.c文件,

只保留了x264_slicetype_decide()函数,其它全部删除421KB
x264_frame_deblocking_filter() 2624,分析这个函数时发现以前将去块内滤波关

掉了,param->b_deblocking_filter = 0;(common.c中),现在将它打开了,
即将其值赋为1,不使用环内滤波的话,图像效果会很差,且误差会扩散.
删除me_en.c中的COST_MV_RD宏
删除analyse_en.c中的x264_intra_rd_refine()函数,所有以if( analysis.b_mbrd

)为条件判断的代码,x264_intra_rd函数,x264_mb_analyse_p_rd()
x264_mb_analyse_transform_rd() (可以考虑删除所有以_rd结尾的函数或变

量);x264_macroblock_encode_p8x8(),x264_mb_analyse_transform()
x264_mb_analyse_inter_p4x4_chroma()函数虽然没有被调用,但是目前还不太明白

其工作,暂未删除
x264_mb_analyse_inter_p8x8_mixed_ref()
x264_mb_cache_mv_b8x8()
删除掉rdo_en.c中的所有函数
删除dct.c中与add16x16_idct8();sub8x8_dct8();等与8x8有关的函数,去掉与i8x8

有关的函数
删除eval_en.c,
   macroblock.c中
删除macroblock.c中的x264_mb_predict_mv_direct16x16

(),x264_mb_predict_mv_direct16x16_temporal

(),x264_mb_transform_8x8_allowed()
static int x264_mb_predict_mv_direct16x16_spatial( x264_t *h

),x264_mb_mc_direct8x8();
x264_mb_mc_01xywh()(可能是对后向参考帧计算的),x264_mb_mc_direct8x8(

x264_t *h, int x, int y ),x264_mb_transform_8x8_allowed()
x264_macroblock_bipred_init(),x264_mb_load_mv_direct8x8

(),x264_mb_mc_1xywh()

2008-04-15 8:30

删除macroblock.h中的I8X8变量
删除mc.c中PIXEL_AVG_WEIGHT_C(),x264_mc_functions_t结构体中的void

(*avg_weight[10])( uint8_t *dst, int, uint8_t *src, int, int i_weight );
ratecontrol_en.c中
删除x264_ratecontrol_mb(),predict_row_size_sum(),predict_size

(),x264_ratecontrol_threads_start(),x264_ratecontrol_start(),
x264_ratecontrol_qp(),..
修改本文件只保留三个函

数:x264_ratecontrol_new,x264_ratecontrol_delete,x264_ratecontrol_end,只保

留x264_ratecontrol_t结构体中的
4个变量:    double fps;double bitrate;int qp_constant[2];int qp;

predict.c中
的x264_predict_8x8_filter()
set_en.c中
删除set_en.c中的scaling_list_write(),这个在x264_pps_write()调用了,本方案

中不满足它运行的条件,也屏蔽掉
transpose()
删除quant.c中static void quant_8x8_core( int16_t dct[8][8], int quant_mf

[8][8], int i_qbits, int f ),
static void quant_8x8(),dequant_8x8(),dequant_8x8()
macroblock.h中
修改enum mb_class_e,static const int x264_mb_type_fix,static const int

x264_mb_type_list0_table
set.c中
删除x264_cqm_parse_file(),x264_cqm_parse_jmlist()
common.c中
删除x264_slurp_file(),x264_nal_decode(),x264_encoder_headers

(),x264_encoder_reconfig()
    frame.c中
删除x264_frame_expand_border_mod16()
macroblock_en.c中
删除x264_denoise_dct()
晚上发现程序对news.yuv,mother & daughter.yuv编码后均出现下半部分模糊,只对

foreman01.yuv正常.一晚上就在解决这个问题
结果发现当时改写encoder_en.c时对if( i_skip > 0 )
{
   bs_write_ue( &h->out.bs, i_skip ); // /* last skip run
    }的情况改错了,导致出现跳跃宏块没编码,所以出现模糊现象
   
2008-04-16 16:24
上午发现本程序只能编码30帧,对于超过30帧的图像不能正确编码,(生成的264文件

大小应该是对的,但用VLC播放时出错)
看来还是得用昨晚的方法(用Beyond Compare比较文件的差别)来解决了,但现在没这

个兴趣了...现就对30帧做优化,以后再解决这个.
软件仿真md.yuv(2帧),生成code coverage and exclusive cyle报告

在VC下程序


define DECLARE_ALIGNED( type, var, n ) type var __attribute__((aligned

(n)))
在CCS下可以如下改造
#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned(8)))

#       define DECLARE_ALIGNED( type, var, n ) __declspec(align(n)) type

var
   DECLARE_ALIGNED( uint8_t, pix1[8*8], 8 );
   DECLARE_ALIGNED( int16_t, dct4x4[16][4][4], 16 );
   DECLARE_ALIGNED( int, luma16x16_dc[16], 16 );
   

#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned(8)))

#       define DECLARE_ALIGNED( uint8_t, var, n ) type var __attribute__

((aligned(8)))
#       define DECLARE_ALIGNED( int16_t, var, n ) type var __attribute__

((aligned(16)))
#       define DECLARE_ALIGNED( int, var, n ) type var __attribute__

((aligned(32)))

#define DECLARE_ALIGNED_8(type, var, n) type, var __attribute__

((aligned(8)))


2008-04-17 12:00
一上午在解决昨天上午发现的问题:不能编码60帧,结果是在set_en.c中

x264_sps_init()中sps->i_num_ref_frames = 1;被屏蔽掉了,MD,真是郁闷
一上午啊!
删除以下
b_transform_8x8,i_mb_count_8x8dct,b_bframe_rdo,x264_level_t


dequant8_mf

h->mb.pic.p_integral[1][i]

h->sh.i_num_ref_idx_l1_active

2008-04-19 21:08
修改X264_malloc

2008-04-21
找到TI的EDMA3_DRV例程(spraan4.zip),这两天在研究这个例程,
通过这个例程,对比发现:使用timer0和timer1对调用CLK_getltime无影响

2008-04-23 15:49
拟用EDMA3传输的:
x264_frame_copy_picture( h, fenc, pic_in );

在x264_picture_alloc()函数中/以后在后期算法优化完成后需注意此处!!!!
暂不分配三个图像缓冲区的空间,(因为在read_frame_yuv中不采用memcpy,而采用

p_pic->img.plane[0] = p_readYUVBuffer;直接指定地址的方式,
在x264_picture_clean中删除x264_free( pic->img.plane[0] );

2008-04-24 8:55
在CCS下(dsp264yh_evm)下,本来是将bs_size_ue采用#pragma CODE_SECTION

(bs_size_ue,".l1d_text")放到L1DSRAM段,但出错,将它放到IRAM中,程序就能
正常运行(莫非是因为L1DSRAM只是支持放数据?但在DSP/BIOS中可以修改其属性为

CODE/DATA啊!!)此时编码md.yuv,1.4fps
使用#pragma DATA_SECTION(fenc_buf,".iram_data"),将fenc_buf和fdec_buf(

当前编码,重构宏块)都放于IRAM中,速度1.8fps
将一些函数放在iram中,1.93fps
使用-o3,-mt优化后,2.214286 fps

环内滤波(x264_fdec_deblock)和帧级滤波(x264_frame_filter)函数均在

encoder_en.c中的x264_reference_update()函数中
2008-04-24 15:50
在x264_macroblock_analyse()函数中
去掉程序中P帧的关于帧内预测的部分,和case D_L0_4x4部分

使用EDMA需要调用edma3_init().
./;$(Proj_dir)/driver;$(Proj_dir)/CSL_inc
_DEBUG;CHIP_DM6437=1;BIOS_BUILD;DM6437_SOC_BUILD;DM643X_SOC_BUILD

LINK
$(Proj_dir)/driver
edma3_drv_bios_dbg.lib;edma3_rm_bios_dbg.lib


2008-04-25 15:54
出现ECM的错误,在DSP/BIOS的HWI中的ECM中应该设置为TRUE即可

2008-04-26 16:42
昨天加了一些关于EDMA3_DRV的程序,然后不知道修改哪儿了,原来的2.214286fps的

程序竟然不能正常运行了,只好恢复到1.82fps的那个
在这个程序中使用了和原来一样多的PRAGMA DATA_SECTION等等,-mt -o3,将L2分配

L2CACHE为32KB(地址-10818000,长度0x8000),96KB的L2RAM(起始地址
0x10800000,长度0x18000),速度仍然只有1.83fps,
将macroblock.c中的fenc_buf和fdec_buf由16字节对齐改成128字节对齐,速度仍是

1.8fps

2008-04-27 9:52
在macroblock.c中加了使用EDMA3_DRV,复制fenc_buf,但只有第一帧数据是

3283bytes貌视正常,第二帧以后均是7bytes,暂未发现原因

2008-04-28 14:12
昨天的问题已经解决,使用相同的QDMA通道即可,但尚未做其优化(2.21fps)

2008-04-28 20:36
修改macroblock.c中的x264_macroblock_cache_init,去掉CHECKED_MALLOC( h-

>mb.qp, i_mb_count * sizeof(int8_t) ),即不给h->mb.qp分配
存储空间,在其它文件中(frame.c)的相应部分也需修改(5处)
去掉(m)->integral = &h->mb.pic.p_integral[list][ref][(xoff)+(yoff)*(m)-

>i_stride[0]]和common.h中的uint16_t *p_integral[2][16];


2008-05-03 14:28
上午在sparan.4例程里看到程序的main函数中使用了, BCACHE_setMar( (Ptr)

(0x80000000), 0x8000000, BCACHE_MAR_ENABLE );即将外部128M设置为
可缓存的,觉得这个是有点学问,这该例程中将这句话删掉,明显感到速度下降很大.
于是这句代码加入到ccs下的x264.c的main函数中,运行,forman.dat,速度

10.333fps!!!,md.dat,速度15.500000 fps!!!并且运行时正确,播放也正确!!!
为与其对比,删掉这句话,forman.dat,速度:1.61fps,md.dat:2.214286 fps.
这句程序的代码是设置外部存储空间可以cachable,其实在DSP/BIOS中也可以设置.
为什么到现在才发现呢?

你可能感兴趣的:(音视频处理学习)