当初做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_on 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的DA 保存为DA DA 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的DA foreman01.dat,以后要作测试时,直接使用 DA 法: 如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./dv_rss.asp? s=xhtml&boardid=20&id=118797) 仍不能解决问题!!! 2008-02-22 15:07 1.尝试方法:恢复1.17号的X264.C文件,即还是采用fopen,fread,从PC上读一帧编码 后再从PC上读另一帧,看是否正常 使用DA 在使用DA 使用类似的程序在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:da 速度30帧大约需要1分钟 对于fps的计算仍未清楚,clock()两次运行同样的程序得到的时间竟然不同! 2008-02-27 21:20 仍然在研究使用何种方法来获得程序运行的时间, clock()只有用load6x()时才较准确, CLK_getltime()是推荐的用法,不过要引入中断 新建一个工作(在F:\DSP\CCS\CLK)专门用来测试CLK_getltime()的用法,发现: 1.只有用timer0时,定时器中断才能进入, 2.使用Pro 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\\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:da 2.-k -pm -op0 -o3 -fr"$(Proj_dir)\Debug" -d"_DEBUG" -mt -mw -mv6400+ -- mem_model:da 昨天使用-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),程序可以跟踪运行.初步得到了CO 小, 发现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 有关的函数 删除ev 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帧),生成co 在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 CO (bs_size_ue,".l1d_text")放到L1DSRAM段,但出错,将它放到IRAM中,程序就能 正常运行(莫非是因为L1DSRAM只是支持放数据?但在DSP/BIOS中可以修改其属性为 CO 使用#pragma DA 当前编码,重构宏块)都放于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 DA 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中也可以设置. 为什么到现在才发现呢? |
|