H.264代码详解全过程_第1页
H.264代码详解全过程_第2页
H.264代码详解全过程_第3页
H.264代码详解全过程_第4页
H.264代码详解全过程_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、x264源代码解析x264编码详细文字全过程x264_param_default(x264_param_t*param)作用:对编码器进行参数设定cqm:量化表相关信息csp:量化表相关信息里的memset(param-cqm_4iy,16,16);memset(param-cqm_4ic,16,16);memset(param-cqm_4py,16,16);memset(param-cqm_4pc,16,16);memset(param-cqm_8iy,16,64);memset(param-cqm_8py,16,64);staticintParse(intargc,char*argv,x2

2、64_param_t*param,cli_opt_t*opt)初始化1getopt_long(nargc,nargv,options,long_options,idx)得到入口地址的向量与方式的选则2getopt_internal(nargc,nargv,options)解析入口地址向量staticintEncode(x264_param_t*param,cli_opt_t*opt)h-param=paramvui信息主要包括帧率、图像尺寸等信息x264_sps_init(h-sps,0,&h-param);序列图像集x264_pps_init(h-pps,0,&h-param,h-sps);

3、图像参数集初始化并开辟帧空间对前一宏块的信息保存,因为是初始化,所以作为第一个宏块的参考,后面会有x264_macroblock_cache_load(h,i_mb_x,i_mb_y);它是将要编码的宏块的周围的宏块的值读进来,要想得到当前块的预测值,要先知道上面,左面的预测值初始化cpu对各种分块的参数设定1x264_t*x264_encoder_open(x264_param_t*param)这个函数是对不正确的参数进行修改,并对各结构体参数和cabac编码,预测等需要的参数进行初始化2、p_read_frame(&pic,opt-hin,i_frame+opt-i_seek,param-

4、i_width,param-i_height)读取一帧,并把这帧设为previ_file+=Encode_frame(h,opt-hout,&pic);进入核心码层核心编码层的总流程图:(x264.c)1x264_encoder_encode(h,&nal,&i_nal,pic,&pic_out)对帧进行编码2i_size=x264_nal_encode(data,&i_data,1,&nali)网络打包编码3i_file+=p_write_nalu(hout,data,i_size)把网络包写入到输出文件中去4返回,对下一帧进行编码下面一页是详细的流程图:一帧内详细流程图:x264_enco

5、der_encode(h,&nal,&i_nal,pic,&pic_out)对帧进行编码1x264_frame_t*fenc=x264_frame_get(h-frames.unused);x264_frame_copy_picture(h,fenc,pic_in);fenc-i_frame=h-frames.i_input+;x264_frame_put(h-frames.next,fenc);x264_frame_init_lowres(h-param.cpu,fenc);/里面包含低象素的扩展,很多for循环,应该是抽头计算和半精度象素的扩展,要认真看(2)264_slicetype_d

6、ecide(h);对slice类型的判定,里面也要看一下(3)while(IS_X264_TYPE_B(h-frames.nextbframes-i_type)bframes+;x264_frame_put(h-frames.current,x264_frame_get(&h-frames.nextbframes);这主要是因为B帧必须等后面的非B帧编码结束后才能编码,所以把暂时不编的一系列B帧存入队列中,一直到非B帧才取出进行编码,之后再进行前面的B帧编码do_encode:(4).建立listO&listl.我感觉x264_reference_build_list(h,h-fdec-i_p

7、oc,i_slice_type);比特率控制初始化x264_ratecontrol_start(h,i_slice_type,h-fenc-i_qpplusl);(5).创建slice的头部数据x264_slice_init(h,i_nal_type,i_slice_type,i_global_qp);(6)i_frame_size=x264_slices_write(h);这是编码的关键了x264_slice_header_write(&h-out.bs,&h-sh,h-i_nal_ref_idc);一些初始化工作for(mb_xy=h-sh.i_first_mb,i_skip=O;mb_x

8、ysh.i_last_mb;mb_xy+)对一个slice中每个宏块进行循环遍历编码,其中constinti_mb_y=mb_xy/h-sps-i_mb_width;和constinti_mb_x=mb_xy%h-sps-i_mb_width;是对宏块位置在slice中的x,y坐标的定位,这个for语句几乎覆盖了整个x264_slices_write()函数x264_macroblock_cache_load(h,i_mb_x,i_mb_y);它是将要编码的宏块的周围的宏块的值读进来,要想得到当前块的预测值,要先知道上面,左面的预测值!*x264_macroblock_analyse(h);重

9、点。通过一系列的SAD算出最优化方案,例如把I帧16U16的宏块分成16个4U4分别计算SAD和与原16U16SAD比较我感觉,在下面一层再详细分析。x264_mb_analyse_intra(扎&analysis,COST_MAX);我感觉是在一个16Q16的SAD,4个8D8的SAD和,16个4U4SAD和中选出最优方式进行,可能我的理解不对,里面的x264_mb_encode_i4x4(h,idx,a-i_qp);i8Q8几个函数的跟踪有问题,跟得我都找不到,要仔细看(现在又能跟到了)这边好像如果是直流分量在这里就进行量化ZIGZAG扫描了,不用等到x264_macroblock_enc

10、ode(h)再完成了x264_analyse_update_cache(h,&analysis);有对色度块的模式选择的计算,好像也有更新信息以为下次的预测作为参考x264_macroblock_encode(h);判断宏块的类型根据判断的类型进行DCT,量化,ZIGZAG,并记录当前的模式为下次编码宏块(亚宏块)做参考ZIGZAG的实现不明白(原来ZIGZAG有宏定义,在上面,现在明白了),反量化和IDCT的过程跟不进去,应该是汇编了!函数如下:(I4D4中x264_mb_encode_i4x4(h,i,i_qp);)x264_mb_dequant_4x4(dct4x4,h-dequant4

11、_mfCQM_4IY,i_qscale);h-dctf.add4x4_idct(p_dst,i_stride,dct4x4);还有,这个函数跟踪不进去,应该是重构图像的反变换吧h-dctf.add4x4_idct(p_dst,i_stride,dct4x4);h-ra4x4_pred_modex264_scan8i=x264_mb_pred_mode4x4_fix(i_mode);这个值到底是怎么根据前面的模式改变的,可能是上面两个函数没能更进去所以模糊对色度块进行编码,QP限制在051之间,选定预测模式(DC的话值全为128)x264_mb_encode_8x8_chroma(h,!IS_I

12、NTRA(h-mb.i_type),i_qp);里面对两个色度信号分别编码,与亮度信号类似求亮度和色度的cbp,完全不明白是怎么求的,需要解决!现在有点明白,每个比特代表子块是不是全为0,但还没有全部明白,色度块cbp中0 x02表示有AC,DC0 x01表示只有DC,利用CBP判断要不要SKIP.,里面还关系到向量预测,明天好好看一下。其中h-mb.qph-mb.i_mb_xy=h-mb.i_last_qp;这个为读下一个qp的保存,不然解码端是读不出下一个qp的,关于CBP的理解还存在问题,他的8位比特各个代表的意思还不是十分明确,反正是对DC,AC的编码的选择。185页有介绍(新一代视频

13、压缩标准毕厚杰)选用CABAC还是CAVLCCABAC的原理实现没仔细看x264_macroblock_cache_save(h);保存以为下次的预测作为参考一些收尾工作,为下次宏块作准备(看的比较粗)x264基于经验和感觉的码率控制策略收藏前提:1high-complexityorhigh-motionscenes,细节将不会很明显,此时高qp也是浪费2wheremotioncompensationworkswell,在景物边沿的失真,只需在一帧中去掉,以后就都不会有.在这里投入有限的bits可以获得最好的图像质量性价比3已经编码一frame,可以预测其他qp下所需bit数.预测距离越远越不

14、精确4随着frame重要性降低,他们只配用更大的qp,i,p,参考bdisposableb.依次降低5H.264支持1frame内不同mb使用不同qp,x264不支持,而由rc返回统一qp。但有那个功能函数存在那个函数仅精确到每一行mb变一次qp所以rc策略如下:2pass:step11pass编码,由qp推断某qp下framesize*0.6符合目标framesize的限制,得到这个qpstep2修改qp以满足requestedtotalsize(total是指整个Gop的大小,分段先编一边再一边)step3encode根据实际大小值修正预测的qp,并额外增加short-termcompen

15、sation,针对开始和结束部分没有很多bits余地的位置.1pass:abr(averagebitrate)step1用半尺寸快速运动估计和SATDresiduals替换1stpass中相关部分,获得预测step2用之前的样本估计scalestep3Overflowcompensation和2pass相似限制filesize牺牲图像质量1pass,:constantbitrate(VBVcompliant)!VBV是指:VideoBufferVerifierTheVideoBufferVerifier(VBV)isamodelhypotheticaldecoderbufferthatwill

16、notoverfloworunderflowwhenfedaconformingMPEGbitstream.包含2个因素.size和造成的delaystep1sameasabrstep2Scalingfactorisbasedonalocalaverage(dependentonVBVbuffersize)insteadofallpastframesstep3stricterOverflowcompensation,additionaltermtohardlimittheQPsiftheVBVisnearempty.nohardlimitisdoneforafullVBV这里更加严格的空限制,

17、防止没有bits可以送出,破坏了cbr的传输1pass,constantratefactor:ConstantRateFactor(orConstantQuality)(1)SameasABR.(2)Thescalingfactorisaconstantbasedonthe-crfargument.(3)Nooverflowcompensationisdone.ratefactor是指:constantquantizer:QPsaresimplybasedonframetype.RC中的蛋鸡悖论:为了计算当前帧中宏块的RDO,需利用已定qp确定当前帧或宏块的cost预测每个宏块的modemvr

18、ef等.ratecontrol是在确定modemvref后决定qp,在此之前qp不能获得。于是rdo与rc不知道先做哪个了.x264命令行参数解释收藏本文对应的是x264命令行模式,VFW方式也用相同的参数,不过是图形界面,可以自己找对应的英文。使用格式:x264默认选项-o输出文件输入文件长x宽输入支持格式:RAW/y4m/avi/avs(编译时可选)输出支持格式:264/mkv/mp4(编译时可选)x264的许多参数可以有-/-两种输入法,笔者也不知道为什么。以下等价参数用“参数1/参数2必需数值格式”表示,参数尾部()内为个人推荐。-h/-help帮助帧类型选项:-I/一keyint整数

19、最大IDR帧间距,默认250-i/一min-keyint整数最小IDR帧间距,默认25-scenecut整数画面动态变化限,当超出此值时插入I帧,默认40-b/bframes整数在IP帧之间可插入的B帧数量最大值,范围016,默认0no-b-adapt关闭自适应B帧判定(-b设为1时可用,其他不推荐)-b-bias整数控制插入B帧判定,范围-100+100,越高越容易插入B帧,默认0-b-pyramid允许B帧做参考帧-no-cabac关闭内容自适应二进制算术编码(CABAC,高效率的熵编码)(会提高速度,但严重影响质量)-r/-ref整数最大参考帧数,范围016,默认1-nf关闭环路滤波(一

20、种除马赛克算法)-f/-filteralpha:beta设置环路滤波的AlphaC和Beta的参数,范围-6-6,默认都为0码率控制选项:-q/-qp整数固定量化模式并设置使用的量化值,范围051,0为无损压缩,默认26-B/-bitrate整数设置平均码率-crf整数质量模式,量化值动态可变(目前不太成熟,质量不如设置固定量化值)-qpmin整数设置最小量化值,范围051,默认10-qpmax整数设置最大量化值,范围051,默认51-qpstep整数设置相邻帧之间的量化值差,范围050,默认4-ratetol小数平均码率模式下,瞬时码率可以偏离的倍数,范围0.1100.0,默认1.0-vbv

21、-maxrate整数平均码率模式下,最大瞬时码率,默认0(与-B设置相同)-vbv-bufsize整数码率控制缓冲区的大小,单位kbit,默认0-vbv-init小数码率控制缓冲区数据保留的最大数据量与缓冲区大小之比,范围01.0,默认0.9-ipratio小数I帧和P帧之间的量化系数,默认1.40pbratio小数P帧和B帧之间的量化系数,默认1.30色度-qp-offset整数色度和亮度之间的量化差,范围-12+12,默认0-p/-pass1|2|3多次压缩码率控制1:第一次压缩,创建统计文件2:按建立的统计文件压缩并输出,不覆盖统计文件,3:按建立的统计文件压缩,优化统计文件-stats

22、字符串统计文件的名称,默认x264_2pass.log-rceq字符串速率控制公式,默认blurCplx八(1-qComp)-qcomp小数线性量化控制,0.0为固定码率,1.0为固定量化值,默认0.6,只用于2-pass和质量模式-cplxblur小数根据相邻帧平滑量化值比例的最大值,范围099.9,默认20.0,只用于2-pass和质量模式-qblur小数对统计文件结果平滑量化值比例的最大值,范围099.9,默认0.5,只用于2-pass-zonesz0/zl/分段量化,格式为:开始帧,结束帧,选项,可选项为:q=整数(量化值)或b二小数(码率倍数)分析选项:-A/一analyse字符串动

23、态块划分方法,默认p8x&b8x8,i8x&i4x4。可选项:p8x8/p4x4/b8x8/i8x8/i4x4;none/all(p4x4需要p8x8.i8x8需要-8x8dct)-direct字符串动态预测方式,默认spatial。可选项:none/spatial/temporal/auto-w/-weightb允许B帧加权预测(可以减少相邻B帧质量低的影响)me字符串对全像素块动态预测搜索的方式,默认hex,可选项:dia:菱形搜索,半径1(快)hex:正六边形搜索,半径2umh:可变半径六边形搜索esa:全面搜索(很慢,而且效果与umh几乎相同)-merange整数-me为umh/esa

24、时的搜索半径,最大64,默认16-m/-subme整数动态预测和分区方式,可选项17,默认5(与压缩质量和时间关系密切,1是7速度的四倍以上)1:用全像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索2:用半像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索3:用半像素块进行动态搜索,对每个块再用质量模式进行四分之一像素块精确搜索4:用快速模式进行四分之一像素块精确搜索5:用质量模式进行四分之一像素块精确搜索:进行I、P帧像素块的速率失真最优化(rdo):进行I、P帧运动矢量及块内部的速率失真最优化(质量最好)一b-rdoB帧也进行rdo,需要一subme在6以

25、上-mixed-refs可以在一帧内使用不同参考帧-no-chroma-me不进行色度的动态预测-bime可以平均B帧参考块的运动矢量-8/8x8dct可以使用8x8的离散余弦变换(DCT)-t/-trellis整数Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,默认00:关闭1:只在最后编码时使用2:一直使用-no-fast-pskip关闭快速P帧跳过检测-no-dct-decimate关闭P帧联合编码(可以增加细节,但也会增大体积)-nr整数噪声去除,范围0100000,默认0cqm字符串设置外部量化矩阵格式,默认flat,可选项:jvt/flat-cqmfile字符

26、串读取JM格式的外部量化矩阵文件,自动忽略其他-cqm*选项-cqm4list设置4x4的量化矩阵,用逗号分开,范围1255的16个整数-cqm8list设置8x8的量化矩阵,用逗号分开,范围1255的64个整数-cqm4i/-cqm4p/-cqm8i/-cqm8p设置I、P帧不同的量化矩阵-cqm4iy/-cqm4ic/-cqm4py/-cqm4pc设置亮度、色度不同的量化矩阵视频标准化选项:这些选项与编码无关,不过如果要用mp4之类的播放器,可以设置,风险自担-sarwidth:height设置长宽比-overscan字符串过扫描线,默认undef(不设置),可选项:show(观看)/cr

27、op(去除)-videoformat字符串视频格式,默认undef,可选项:component/pal/ntsc/secam/mac/undef一fullrange字符串Specifyfullrangesamplessetting,默认off,可选项:off/on(我也不明白这是干什么的,请高手指点)一colorprim字符串原始色度格式,默认undef,可选项:undef/bt709/bt470m/bt470bg,smpte170m/smpte240m/film-transfer字符串转换方式,默认undef,可选项:undef/bt709/bt470m/bt470bg/linear,log

28、100/log316/smpte170m/smpte240m一colormatrix字符串色度矩阵设置,默认undef,undef/bt709/fcc/bt470bg,smpte170m/smpte240m/GBR/YCgCo-chromaloc整数色度样本指定,范围05,默认0输入、输出选项:-level字符串设定等级(asdefinedbyAnnexA)(不明白,请高手指点)-fps小数设定帧率-seek整数设定起始帧-frames整数最大编码帧数-o/-output指定输出文件-threads整数编码线程(使用分片技术)-thread-input在编码线程中运行Avisynth-no-a

29、sm关闭全部CPU优化指令-no-psnr关闭PSNR计算-quiet安静模式-v/-verbose显示每一个帧的信息-progress显示编码进程-visualize显示运动矢量-sps-id整数设置SPS和PPS的ID值,默认0-aud使用数据单元定义符号x264中重要结构体说明收藏首先解释一下Cli_opt_t的这个_t代表结构图可能是type的意思。同时还有很多i_b_等作为前缀的变量,其中的1_表示int类型的变量b表示bool类型的。依次类推。正式进入主题。typedefstruCtintb_progress;inti_seek;hnd_thin;hnd_thout;FILE*qp

30、file;Cli_opt_t;此结构体是记录一些与编码关系较小的设置信息的opt=option。结构体内部的变量都可以通过读取main()的参数获得。也就是argv。b_progress表示一个bool类型的变量,看参数帮助也就是x264-help你会知道,他是用来控制是否显示编码进度的一个东西。取值为0,1.I_seek整数类型表示开始从哪一帧编码。因为不一定从这个文件的第一帧开始编码,这是可以控制的。Hnd_t(hnd二handle)是一空指针,void*在C语言里空指针是有几个特性的,他是一般化指针,可以指向仸何一种类型,但却不能解引用,需要解引用的时候,需要进行强制转换。采用空指针的策

31、略,应该是为了声明变量的简便和统一。Hin指向输入yuv文件的指针。Hout指向编码过后生成的文件的指针。Qpfile是一个指向文件类型的指针,他是文本文件,其每一行的格式是framenumframetypeQP用于强制指定某些帧或者全部帧的帧类型和QP(quantparam量化参数)的值。x264_param_default(¶m);这部分设置编码参数的缺省值附结构体param中部分变量的意义:param-i_Csp=X264_CSP_I420;/设置输入的视频采样的格式param-vui.i_sar_width=0;/VUI:videousabilityinformationpar

32、am-i_fps_num=10;/帧率param-i_fps_den=1;/用两个整型的数的比值,来表示帧率param-i_frame_referenCe=1;/参考帧的最大帧数。param-i_bframe=0;/两个参考帧之间的B帧数目。param-b_deblocking_filter=1;/去块效应相关param-b_cabac=0;/cabac的开关param-i_cabac_init_idc=-1;param-rc.b_cbr=1;/constantbitrate恒定码率控制模式param-rc.i_bitrate=0;/默认的码率param-rc.i_rc_buffer_size

33、=0;/buffer的大小param-rc.i_rc_init_buffer=0;/param-rc.i_rc_sens=100;/整个param的一个log文件param-ra=X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;/桢内分析param-er=X264_ANALYSE_I4x4|X264_ANALYSE_I8x8|X264_ANALYSE_PSUB16x16|X264_ANALYSE_BSUB16x16;/桢间分析param-analyse.i_direct_mv_pred=X264_DIRECT_PRED_SPATIAL;/预测模式param-analys

34、e.i_me_method=X264_ME_HEX;/运动估计模式param-analyse.i_me_range=16;/运动估计范围param-analyse.i_subpel_refine=5;param-analyse.b_chroma_me=1;param-analyse.i_mv_range_thread=-1;param-analyse.i_mv_range=-1;/setfromlevel_idcparam-analyse.i_direct_8x8_inference=-1;/setfromlevel_idcparam-analyse.i_chroma_qp_offset=0;

35、param-analyse.b_fast_pskip=1;param-analyse.b_dct_decimate=1;param-analyse.i_luma_deadzone0=21;param-analyse.i_luma_deadzone1=11;param-analyse.b_psnr=1;param-analyse.b_ssim=1;param-i_cqm_preset二X264_CQM_FLAT;/自定义量化矩阵(CQM),初始化量化模式为flattypedefstructinti_type;inti_type;inti_qpplus1;inti_qpplus1;int64_ti

36、_pts;x264_image_timg;x264_picture_t;具体的含义理解参考了read_frame_yuv()x264_picture_alloc();I_type指明被编码图像的类型,有X264_TYPE_AUTOX264_TYPE_IDRX264_TYPE_IX264_TYPE_PX264_TYPE_BREFX264_TYPE_B可供选择,初始化为AUTO,说明由x264在编码过程中自行控制。I_qpplus1:此参数减1代表当前画面的量化参数值。I_pts:programtimestamp程序时间戳,指示这幅画面编码的时间戳。Img:存放真正一副图像的原始数据。typede

37、fstructinti_csp;inti_plane;inti_stride4;uint8_t*plane4;x264_image_t;Csp:colorspaceparameter色彩空间参数X264只支持I420i_Plane代表色彩空间的个数。一般为3,YUV,初始化为x264常用options整理收藏x264源码解析2009年11月12日星期四22:44http:/mingjiang_apple/blog/item/aed41f08efbl0b3ae82488eb.htmlx264源码解析(01)由main函数进入参数设置后开始Encode函数。这里只把Encode函数体解析下借鉴了很

38、多网上资源(即使不全是自己原话也是亲手打字上去的哦,感谢网友。代码似懂非懂的注释了下,尽当资源存储吧吧,暂且发到博客大家讨论批评。staticintEncode(x264_param_t*param,cli_opt_t*opt)x264_t*h;/还不知道干啥的,这个结构也很烦,不压x264_param_tx264_picture_tpic;/一帧的结构体,色度存储inti_frame,i_frame_total;int64_ti_start,i_end;/用来计算时间int64_ti_file;inti_frame_size;inti_update_interval;charbuf200;o

39、pt-b_progress&=param-i_log_levelhin);i_frame_total-=opt-i_seek;if(i_frame_total=0|param-i_frame_totali_frame_total0)i_frame_total=param-i_frame_total;param-i_frame_total=i_frame_total;/上面这段代码是实现,计算文件中的总共的帧数,并根据输入的参数初始帧的位置,/对i_frame_total做出修正,i_frame_total-=opt-i_seek,然后再根据param-i_frame_total,/对i_fra

40、me_total做出进一步的修正。/总体来说,就是对参数设置中的进行编码的帧数的总数进行修正和计算。i_update_interval=i_frame_total?x264_clip3(i_frame_total/1000,1,10):10;if(h=x264_encoder_open(param)=NULL)/关键函数:x264_encoder_open(param)根据参数要求对encoder进行一系列的初始化,例如分配内存,值的初始化等。(略)if(p_set_outfile_param(opt-hout,param)/关键函数:p_set_outfile_param()设置输出文件格式

41、(略)/关键函数:x264_picture_alloc()按照色度空间分配内存,并返回内存的首地址作为指针if(x264_picture_alloc(&pic,X264_CSP_I420,param-i_width,param-i_height)0)(略)/关键函数:x264_mdate()用于编码用时的计算,设定起始时间i_start=x264_mdate();for(i_frame=0,i_file=0;b_ctrl_c=0&(i_framehin提供的输入文件的地址,读入图像的内容到&pic提供的存储区的首地址if(p_read_frame(&pic,opt-hin,i_frame+op

42、t-i_seek)break;pic.i_pts=(int64_t)i_frame*param-i_fps_den;if(opt-qpfile)parse_qpfile(opt,&pic,i_frame+opt-i_seek);/parse_qpfile()为从指定的文件中读入qp的值留下的接口,qpfile为文件的首地址elsepic.i_type=X264_TYPE_AUTO;pic.i_qpplus1=0;/参数减1代表当前画面的量化参数值i_frame_size=Encode_frame(h,opt-hout,&pic);/用于显示整个编码过程的进度if(opt-b_progress&

43、i_frame%i_update_interval=0)int64_ti_elapsed=x264_mdate()-i_start;/编码使用的时间计算/帧率的计算doublefps=i_elapsed0?i_frame*1000000./i_elapsed:0;doublebitrate=(double)i_file*8*param-i_fps_num/(double)param-i_fps_den*i_frame*1000);(略)SetConsoleTitle(buf);fflush(stderr);/neededinwindows/后边的除了清理工作,其他的还不知道。return0;1

44、、x264学习笔记(9)-x264中16x16运动搜索过程函数实现是函数staticvoidx264_mb_analyse_inter_p16x16(x264_t*h,x264_mb_analysis_t*a)1、大循环是参考帧的循环,从最近的一个参考帧开始搜索,一直到最远的一个参考帧;2、调用x264_mb_predict_mv_16x16函数,以上、右上、左块运动矢量的中值m.mvp作为候选运动矢量。3、调用x264_mb_predict_mv_ref16x16函数,寻找其它候选运动矢量。这些候选者包括:空间相邻的左、左上、上、右上块的MV;第0个参考帧中的当前块、右边块、下边快运动矢量乘

45、以时间差权重。4、调用x264_me_search_ref进行运动搜索。搜索时先从所有候选运动矢量中选出最佳的起点,然后使用小钻石法、六边形法、UMH或者全搜索搜索出最佳的整像素位置。5、x264_me_search_ref调用refine_subpel进行1/2和1/4运动搜索。两者都使用小钻石法。6、搜索出最佳运动矢量后,如果当前是最近一个参考帧,而且最佳SA(T)D小与检测门限,则尝试对其进行P_SKIP编码。7、保存搜索结果。2、x264学习笔记(10)-分像素的运动估计总结得到分像素的值函数是下面两个函数,对照着(1)staticuint8_t*get_ref(uint8_t*src

46、4,inti_src_stride,uint8_t*dst,int*i_dst_stride,intmvx,intmvy,inti_width,inti_height)intqpel_idx=(mvy&3)2)*i_src_stride+(mvx2);/偏移到所选的整像素点uint8_t*src1=srchpel_ref0qpel_idx+offset+(mvy&3)=3)*i_src_stride;这里面的4+2的这个2代表色度,而这个4分别代表整像素,在整像素水平右边的1/2像素,在整像素垂直下面的1/2像素和整像素右下角的1/2像素。1/2像素的值已经在前面函数里面插值存好了,只要调用就

47、可以了,而如果要进行1/4像素估计,要临时插值。现在这个函数get_ref中,srcO、srcl、src2、src3这传进来的就是分别是IN,lH,lV,lHV*/if(qpel_idx&5)uint8_t*src2=srchpel_ref1qpel_idx+offset+(mvx&3)=3);pixel_avg(dst,*i_dst_stride,src1,i_src_stride,src2,i_src_stride,i_width,i_height);/1/4搜索时需要临时插值函数returndst;else*i_dst_stride=i_src_stride;returnsrc1;按照毕

48、厚杰的新一代视频压缩编码标准H.264/AVC关于运动矢量那一节的介绍。看图6.22那四个像素点,G为整像素点b、h、i分别是lH,lV,lHV,也就是水平,垂直和对角线的值。Gbhi对应为src0src1src2src3现在看这两个数组staticconstinthpel_ref016=0,1,1,1,0,1,1,1,2,3,3,3,0,1,1,1;staticconstinthpel_ref116=0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2;也按像素的平面图画出来的话srchpel_ref0qpel_idx为0111011123330111srchpel_ref1qpe

49、l_idx为0000223222322232这上面的数字0、1、2、3分别代表整像素、水平1/2像素值、垂直1/2像素值和对角线1/2像素值,也就是毕厚杰书中的G、b、h、I。这里要注意srchpel_ref0qpel_idx最后一行的0111和srchpel_reflqpel_idx最右边一列0222不是当前的整像素0的1/2像素,而分别是其下面和右边一个整像素的对应的1/2像素值,因为(mvy&3)=3)*i_src_stride和(mvx&3)=3)。为什么要这么来排,是因为要根据1/4像素是通过1/2像素线性插值的公式来的,具体看下面这个函数。(2)staticinlinevoidpi

50、xel_avg(uint8_t*dst,inti_dst_stride,uint8_t*src1,inti_src1_stride,uint8_t*src2,inti_src2_stride,inti_width,inti_height)/1/4搜索时需要临时插值函数intx,y;for(y=0;yi_height;y+)for(x=0;x1;/利用相邻半像素和两个像素取平均插值dst+=i_dst_stride;src1+=i_src1_stride;src2+=i_src2_stride;不过最后我有个疑问,那就是1/4插值后,应该原来的1/2值保持不变的.但是分析发现,这个b、h、i这三

51、个1/2像素中,h和i是不变的,不过b会发生变化.个人觉得staticconstinthpel_ref116=0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2;如果改为staticconstinthpel_ref116=0,0,1,0,2,2,3,2,2,2,3,2,2,2,3,2;则b也不会发生变化.所以这里打个问号?3、x264学习笔记(11)-关于运动矢量MV不传输的问题昨天看到H.264乐园群里面有人在讨论运动矢量MV不用传输的问题,就去看了下x264源代码,作个总结编码端:运动估计搜索得到的运动矢量MV是不需要传送的,需要传送的是MVD,MVD即运动矢量MV(运动估计得

52、到)和运动矢量的预测矢量MVP(预测得到)的差值。MVD=MV-MVP解码端:通过预测得到MVP,将传输过来的MVD和MVP相加得到MV=MVD+MVP,然后用这个MV去参考帧中获取预测象素值,最后把这个预测值和残差加一起,作为重构像素值x264中把这个过程放在了熵编码阶段,在这个函数里x264_macroblock_write_cabacMVD并保存下来以备传输的函数如下:staticinlinevoidx264_cabac_mb_mvd(x264_t*h,x264_cabac_t*cb,inti_list,intidx,intwidth,intheight)intmvp2;intmdx,m

53、dy;x264_mb_predict_mv(h,i_list,idx,width,mvp);/预测MVPmdx=h-mb.cache.mvi_listx264_scan8idx0-mvpO;/计算MVDmdy=h-mb.cache.mvi_listx264_scan8idx1-mvp1;x264_cabac_mb_mvd_cpn(h,cb,i_list,idx,0,mdx);/编码x264_cabac_mb_mvd_cpn(h,cb,i_list,idx,1,mdy);x264_macroblock_cache_mvd(h,block_idx_xidx,block_idx_yidx,width

54、,height,i_list,mdx,mdy);/保存MVD4、firstimeMV预测过程详解(附图)=第一步:确定相邻块=MV预测以宏块分割(或亚宏块分割,如果宏块存在亚分割)为单位,同一个宏块分割(或亚宏块分割)内所有4*4块MV预测值相同。以每个宏块分割(或亚宏块分割)的左上角像素pixel1和右上角像素pixel2为参考点来确定相邻块则:pixel1左侧相邻像素所在4*4块为当前宏块分割(或亚宏块分割)的相邻块Apixel1上方相邻像素所在4*4块为当前宏块分割(或亚宏块分割)的相邻块Bpixel2右上对角线像素所在4*4块为当前宏块分割(或亚宏块分割)的相邻块Cpixel1左上对角

55、线像素所在4*4块为当前宏块分割(或亚宏块分割)的相邻块D图片附件:MV预测示意图JPG(2006-9-2911:14AM,85.25K)以最复杂的8*8宏块分割类型为例(此时只存在亚宏块分割),分析如下:假设图中黑色框表示宏块、每个绿色框表示一个4*4块、每个红色框表示一个8*8块。当前宏块的宏块分割模式为8*8(如图中红色线),其亚宏块分割模式分别为:第一个8*8块为8*8,第二个8*8块为4*4(如图中蓝色线),第三个8*8块为4*8(如图中蓝色线),第四个8*8块为8*4(如图中蓝色线)。则按照上述方法来确定相邻块的方法如下:第一个预测对象为第一个8*8块,以其左上角像素pixel1和右上角像素pixel2为参考点,则:A为7号4*4块,B为2号4*4块,C为4号4*4块,D为1号4*4块。9、14、15与8具有相同MV预测值第二个预测对象为第二个8*8块的第一个4*4块,即10号块,以其左上角像素pixel1和右上角像素pixel2为参考点,则:A为9号4*4块,B为4号4*4块,C为号4*4块,D为3号4*4块第三个预测对象为第二个8*8块的第二个4*4块,即11号块,以其左上角像素pixel1和右上角像素pixel2为参考点,则:A为10号4*4块,B为5号4*4块,C为号4*4块,D为4号4*4块第四个预测对象为第二个8*8块的第三个4*4块,即16号块

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论