目录

  • 帧内预测算法原理
    • 基于论文的普通介绍
  • 硬件实现
    • 亮度块与色度块的划分
    • 4×4亮度预测模块
    • 如何产生预测像素与残差像素?
      • 垂直模式`INTRA4x4_V`
      • 水平模式`INTRA4x4_H`
      • 直流模式`INTRA4x4_DC`

前述文章链接在此~~
H.264视频编解码的FPGA源码分析(一)输入数据分析

帧内预测算法原理

基于论文的普通介绍

  1. 目的:提高I帧压缩性能
  2. 核心思想:利用图像内部特别是图像平滑部分相邻像素间的相关性来降低编码码率,也就是通过减少空间冗余来实现压缩
  3. 使用当前编码的宏块上方以及左方的宏块,计算当前宏块的预测值,再将预测值与实际的像素值相减得到预测残差,编码的时候只对预测残差进行编码(有点像残差神经网络的思想嘿嘿嘿)
  4. 4种帧内预测模式:4×4亮度块预测(intra_4×4),16×16亮度块预测(intra_16×16),8×8色度块预测(intra_chroma),PCM预测方式(I_PCM)

硬件实现

亮度块与色度块的划分

我们来复习一下,上一篇文章中我们已经分析出,信号mc_cur_umc_cur_v是连接8×8色度块以及帧内预测模块,连接方式为:

mb_cb mc_cur_u
mb_cr mc_cur_v

然后来看这个数据去了哪里

genvar j;
generate for(j=0;j<64; j=j+1) begin:j_nalways @( * ) begincur_u[j] = mb_cb[(j+1)*8-1:j*8];cur_v[j] = mb_cr[(j+1)*8-1:j*8];  endend
endgenerate

这里的cur_ucur_v是寄存器数组,定义如下:

reg [`BIT_DEPTH-1:0]        cur_u[0:63];
reg [`BIT_DEPTH-1:0]       cur_v[0:63];

然后这个数据~~

always @(*) begincase (chroma_num)3'b000:ori_uv={cur_u[0],  cur_u[1],  cur_u[2],  cur_u[3],cur_u[8],  cur_u[9],  cur_u[10], cur_u[11],cur_u[16], cur_u[17], cur_u[18], cur_u[19],cur_u[24], cur_u[25], cur_u[26], cur_u[27] };3'b001:ori_uv={cur_u[4],  cur_u[5],  cur_u[6],  cur_u[7],cur_u[12], cur_u[13], cur_u[14], cur_u[15],cur_u[20], cur_u[21], cur_u[22], cur_u[23],cur_u[28], cur_u[29], cur_u[30], cur_u[31] };3'b010:ori_uv={cur_u[32], cur_u[33], cur_u[34], cur_u[35],cur_u[40], cur_u[41], cur_u[42], cur_u[43],cur_u[48], cur_u[49], cur_u[50], cur_u[51],cur_u[56], cur_u[57], cur_u[58], cur_u[59] };3'b011:ori_uv={cur_u[36], cur_u[37], cur_u[38], cur_u[39],cur_u[44], cur_u[45], cur_u[46], cur_u[47],cur_u[52], cur_u[53], cur_u[54], cur_u[55],cur_u[60], cur_u[61], cur_u[62], cur_u[63] };    3'b100:ori_uv={cur_v[0],  cur_v[1],  cur_v[2],  cur_v[3],cur_v[8],  cur_v[9],  cur_v[10], cur_v[11],cur_v[16], cur_v[17], cur_v[18], cur_v[19],cur_v[24], cur_v[25], cur_v[26], cur_v[27] };3'b101:ori_uv={cur_v[4],  cur_v[5],  cur_v[6],  cur_v[7],cur_v[12], cur_v[13], cur_v[14], cur_v[15],cur_v[20], cur_v[21], cur_v[22], cur_v[23],cur_v[28], cur_v[29], cur_v[30], cur_v[31] };3'b110:ori_uv={cur_v[32], cur_v[33], cur_v[34], cur_v[35],cur_v[40], cur_v[41], cur_v[42], cur_v[43],cur_v[48], cur_v[49], cur_v[50], cur_v[51],cur_v[56], cur_v[57], cur_v[58], cur_v[59] };3'b111:ori_uv={cur_v[36], cur_v[37], cur_v[38], cur_v[39],cur_v[44], cur_v[45], cur_v[46], cur_v[47],cur_v[52], cur_v[53], cur_v[54], cur_v[55],cur_v[60], cur_v[61], cur_v[62], cur_v[63] };endcase
end

这种整齐的代码看起来简直不要太爽
可以看到case的状态变量是chroma_num,这个变量是来自模块intra_16x16_chroma_top

intra_16x16_chroma_top u_intra_16x16_chroma_top(.clk             ( clk               ),    .rst_n                ( rst_n             ),    .mb_x_total           ( mb_x_total        ),    .mb_x             ( mb_x              ),    .mb_y             ( mb_y              ),   .pred_start_i      ( i16x16_chroma_start ),.pred_done_o        ( i16x16_chroma_done  ),.i16x16_rec_start_i ( i16x16_rec_start  ),.i16x16_rec_done_o  ( i16x16_rec_done   ),.chroma_rec_start_i ( chroma_rec_start  ),.chroma_rec_done_o  ( chroma_rec_done   ),.luma_16x16_cost_o  ( i16x16_cost       ),.chroma_8x8_cost_o    ( chroma_cost       ),                .luma_16x16_sel_o   ( i16x16_num        ),.chroma_8x8_sel_o   ( chroma_num        ),

篇幅所限我这里只截取模块实例化的一部分代码
也就是说,模块接收来自intra_16x16_chroma的指示信号,然后根据这个信号的值来对ori_uv这个变量赋值,变量定义为:

reg [`BIT_DEPTH*16-1:0]     ori_uv;

是一个8*16=128bit的寄存器变量,这里case了8种情况,没有default但是因为已经包含了所有可能的情况,所以不会出现锁存器。chroma_num主要是指示要把哪些数据赋值给ori_uv。但这里我第一次看的时候没注意,其实cur_vcur_u是不同的

{cur_u[{addr_uv, 2'b00}],cur_v[{addr_uv, 2'b00}],cur_u[{addr_uv, 2'b01}],cur_v[{addr_uv, 2'b01}],
cur_u[{addr_uv, 2'b10}],cur_v[{addr_uv, 2'b10}],cur_u[{addr_uv, 2'b11}],cur_v[{addr_uv, 2'b11}]} <= pdata_i;

也就是说cur_vcur_u是交替赋值的。

这里我个人其实没有理解是怎么赋值的,氮素~我们可以通过仿真来直观的看一下这个赋值的过程。把从pdata开始到ori_uv的代码单独抠出来仿真一下,试试看!let’s go!

开始计数,pdata一次取出64bit,第一个数是525956565d575355
对应文件中的数

可以看到一次取两行数据

可以看到当pvalid_i变为高之后,addr_p开始计数,然后下一个时钟周期,cur_y开始赋值,一个周期赋值64bit数据。与此同时,addr_y(5bit)和addr_uv(4bit)同步开始计数。


addr_p(6bit)的最高位变成1,下一个周期cur_u开始赋值,采用pdata_i隔一个赋一个,只取了32bit 的数据。

一个16×16的亮度宏块,和两个8×8的色度宏块
实在是看不出来是什么东西。。。
那么为什么要这么划分呢?这个就要涉及到YUV的编码格式:YUV中的Y代表亮度(luma),CbCr代表色度(chroma)。常见的有三种格式:YUV444,YUV422,YUV420。第一个数字4代表4个图像像素中,每个都有亮度值,第二个数字代表U,表示四个图形像素中,Cb只占两个像素,第三个数字代表V。具体的可以参考下图

所以这里的赋值方法大概就是类似于倒数第一种or倒数第三种?

4×4亮度预测模块

可以看到由intra_4×4模块发出一个指示信号i4x4_num

intra_4x4_top u_intra_4x4_top(.clk               ( clk               ), .rst_n               ( rst_n             ), .mb_x_total          ( mb_x_total        ), .mb_x                ( mb_x              ), .mb_y                ( mb_y              ), .start_i             ( i4x4_start        ),.done_o               ( i4x4_done         ),.lambda_i             ( lambda            ),.luma_4x4_cost_o      ( i4x4_cost         ),.i4x4_num_o           ( i4x4_num          ),

这个信号用于指示cur_y数据的分配

always @(*) begincase (i4x4_num)4'b0000:ori4x4 ={ cur_y[0],   cur_y[1],   cur_y[2],   cur_y[3],cur_y[16],  cur_y[17],  cur_y[18],  cur_y[19],cur_y[32],  cur_y[33],  cur_y[34],  cur_y[35],cur_y[48],  cur_y[49],  cur_y[50],  cur_y[51] };4'b0001:ori4x4 ={ cur_y[4],   cur_y[5],   cur_y[6],   cur_y[7],cur_y[20],  cur_y[21],  cur_y[22],  cur_y[23],cur_y[36],  cur_y[37],  cur_y[38],  cur_y[39],cur_y[52],  cur_y[53],  cur_y[54],  cur_y[55] };4'b0010:ori4x4 ={ cur_y[64],  cur_y[65],  cur_y[66],  cur_y[67],cur_y[80],  cur_y[81],  cur_y[82],  cur_y[83],cur_y[96],  cur_y[97],  cur_y[98],  cur_y[99],cur_y[112], cur_y[113], cur_y[114], cur_y[115] };4'b0011:ori4x4 ={ cur_y[68],  cur_y[69],  cur_y[70],  cur_y[71],cur_y[84],  cur_y[85],  cur_y[86],  cur_y[87],cur_y[100], cur_y[101], cur_y[102], cur_y[103],cur_y[116], cur_y[117], cur_y[118], cur_y[119] };4'b0100:ori4x4 ={ cur_y[8],   cur_y[9],   cur_y[10],  cur_y[11],cur_y[24],  cur_y[25],  cur_y[26],  cur_y[27],cur_y[40],  cur_y[41],  cur_y[42],  cur_y[43],cur_y[56],  cur_y[57],  cur_y[58],  cur_y[59] };4'b0101:ori4x4 ={ cur_y[12],  cur_y[13],  cur_y[14],  cur_y[15],cur_y[28],  cur_y[29],  cur_y[30],  cur_y[31],cur_y[44],  cur_y[45],  cur_y[46],  cur_y[47],cur_y[60],  cur_y[61],  cur_y[62],  cur_y[63] };4'b0110:ori4x4 ={ cur_y[72],  cur_y[73],  cur_y[74],  cur_y[75],cur_y[88],  cur_y[89],  cur_y[90],  cur_y[91],cur_y[104], cur_y[105], cur_y[106], cur_y[107],cur_y[120], cur_y[121], cur_y[122], cur_y[123] };4'b0111:ori4x4 ={ cur_y[76],  cur_y[77],  cur_y[78],  cur_y[79],cur_y[92],  cur_y[93],  cur_y[94],  cur_y[95],cur_y[108], cur_y[109], cur_y[110], cur_y[111],cur_y[124], cur_y[125], cur_y[126], cur_y[127] };4'b1000:ori4x4 ={ cur_y[128], cur_y[129], cur_y[130], cur_y[131],cur_y[144], cur_y[145], cur_y[146], cur_y[147],cur_y[160], cur_y[161], cur_y[162], cur_y[163],cur_y[176], cur_y[177], cur_y[178], cur_y[179] };4'b1001:ori4x4 ={ cur_y[132], cur_y[133], cur_y[134], cur_y[135],cur_y[148], cur_y[149], cur_y[150], cur_y[151],cur_y[164], cur_y[165], cur_y[166], cur_y[167],cur_y[180], cur_y[181], cur_y[182], cur_y[183] };4'b1010:ori4x4 ={ cur_y[192], cur_y[193], cur_y[194], cur_y[195],cur_y[208], cur_y[209], cur_y[210], cur_y[211],cur_y[224], cur_y[225], cur_y[226], cur_y[227],cur_y[240], cur_y[241], cur_y[242], cur_y[243] };4'b1011:ori4x4 ={ cur_y[196], cur_y[197], cur_y[198], cur_y[199],cur_y[212], cur_y[213], cur_y[214], cur_y[215],cur_y[228], cur_y[229], cur_y[230], cur_y[231],cur_y[244], cur_y[245], cur_y[246], cur_y[247] };                                        4'b1100:ori4x4 ={ cur_y[136], cur_y[137], cur_y[138], cur_y[139],cur_y[152], cur_y[153], cur_y[154], cur_y[155],cur_y[168], cur_y[169], cur_y[170], cur_y[171],cur_y[184], cur_y[185], cur_y[186], cur_y[187] };4'b1101:ori4x4 ={ cur_y[140], cur_y[141], cur_y[142], cur_y[143],cur_y[156], cur_y[157], cur_y[158], cur_y[159],cur_y[172], cur_y[173], cur_y[174], cur_y[175],cur_y[188], cur_y[189], cur_y[190], cur_y[191] };4'b1110:ori4x4 ={ cur_y[200], cur_y[201], cur_y[202], cur_y[203],cur_y[216], cur_y[217], cur_y[218], cur_y[219],cur_y[232], cur_y[233], cur_y[234], cur_y[235],cur_y[248], cur_y[249], cur_y[250], cur_y[251] };4'b1111:ori4x4 ={ cur_y[204], cur_y[205], cur_y[206], cur_y[207],cur_y[220], cur_y[221], cur_y[222], cur_y[223],cur_y[236], cur_y[237], cur_y[238], cur_y[239],cur_y[252], cur_y[253], cur_y[254], cur_y[255] };endcase
end

总共是16种情况

assign ori00_4x4 = ori4x4[127:120];
assign ori01_4x4 = ori4x4[119:112];
assign ori02_4x4 = ori4x4[111:104];
assign ori03_4x4 = ori4x4[103: 96];
assign ori10_4x4 = ori4x4[ 95: 88];
assign ori11_4x4 = ori4x4[ 87: 80];
assign ori12_4x4 = ori4x4[ 79: 72];
assign ori13_4x4 = ori4x4[ 71: 64];
assign ori20_4x4 = ori4x4[ 63: 56];
assign ori21_4x4 = ori4x4[ 55: 48];
assign ori22_4x4 = ori4x4[ 47: 40];
assign ori23_4x4 = ori4x4[ 39: 32];
assign ori30_4x4 = ori4x4[ 31: 24];
assign ori31_4x4 = ori4x4[ 23: 16];
assign ori32_4x4 = ori4x4[ 15:  8];
assign ori33_4x4 = ori4x4[  7:  0];
intra_4x4_top u_intra_4x4_top(.clk               ( clk               ), .rst_n               ( rst_n             ), .mb_x_total          ( mb_x_total        ), .mb_x                ( mb_x              ), .mb_y                ( mb_y              ), .start_i             ( i4x4_start        ),.done_o               ( i4x4_done         ),.lambda_i             ( lambda            ),.luma_4x4_cost_o      ( i4x4_cost         ),.i4x4_num_o           ( i4x4_num          ),.i4x4_end_o           ( i4x4_end          ),.i4x4_pred_mode_i     ( i4x4_pred_mode    ),.i4x4_min_mode_o      ( i4x4_min_mode     ),.i4x4_min_val_o       ( i4x4_min_val      ),.i4x4_min_num_o       ( i4x4_min_num      ),.tq_en_o              ( tq_i4x4_en_o      ),.tq_mod_o             ( tq_i4x4_mod_o     ),.tq_num_o             ( tq_i4x4_num_o     ),.tq_end_o             ( tq_i4x4_end_o     ),.tq_min_o             ( tq_i4x4_min_o     ),              .ori00 ( ori00_4x4 ), .ori01 ( ori01_4x4 ), .ori02 ( ori02_4x4 ), .ori03 ( ori03_4x4 ),.ori10 ( ori10_4x4 ), .ori11 ( ori11_4x4 ), .ori12 ( ori12_4x4 ), .ori13 ( ori13_4x4 ),.ori20 ( ori20_4x4 ), .ori21 ( ori21_4x4 ), .ori22 ( ori22_4x4 ), .ori23 ( ori23_4x4 ),.ori30 ( ori30_4x4 ), .ori31 ( ori31_4x4 ), .ori32 ( ori32_4x4 ), .ori33 ( ori33_4x4 ),

下面我们跳到这个intra_4×4模块
对应的定义

// Original Pixel Input
input  [`BIT_DEPTH-1:0]        ori00, ori01, ori02, ori03,ori10, ori11, ori12, ori13,ori20, ori21, ori22, ori23,ori30, ori31, ori32, ori33;
// Reference Pixel Input
input  [`BIT_DEPTH-1:0]        ref00tl,                            ref00t,  ref01t,  ref02t,  ref03t,  ref00l,  ref01l,  ref02l,  ref03l,  ref00tr, ref01tr, ref02tr, ref03tr;
// Predicted Pixel Output
output  [`BIT_DEPTH-1:0]   pre00, pre01, pre02, pre03,pre10, pre11, pre12, pre13,pre20, pre21, pre22, pre23,pre30, pre31, pre32, pre33;
// Residual Data Output
output  [`BIT_DEPTH:0]     res00, res01, res02, res03,res10, res11, res12, res13,res20, res21, res22, res23,res30, res31, res32, res33;

好我们来分析一下。
cur_y是一个8bit位宽,深度为256的寄存器数组,但是在4×4的帧内预测模块中,是以一个44子块作为单元来实现的。于是就将其划分为44的子块,其中行是连续的,但是行与行之间的数据是不连续的。然后转化为串行数据,传递给4×4的帧内预测模块进行处理。
这里还涉及到了一个参考信号,看一下这个信号是什么。

定义

// Ref Pixels for Intra_4x4
wire [`BIT_DEPTH-1:0] ref4x4_00tl,                                      ref4x4_00t,  ref4x4_01t,  ref4x4_02t,  ref4x4_03t,ref4x4_00l,  ref4x4_01l,  ref4x4_02l,  ref4x4_03l,ref4x4_00tr, ref4x4_01tr, ref4x4_02tr, ref4x4_03tr;

可以看到是从模块intra_ref产生。【这里我们下次介绍】

如何产生预测像素与残差像素?

进入这个模块:

intra_4x4_pe u_intra_4x4_pe (.clk        ( clk               ),.rst_n        ( rst_n             ),.curr_mode    ( i4x4_curr_mode    ),.blk_avail    ( blk_avail         ),.pixel_ori00( ori00 ), .pixel_ori01( ori01 ), .pixel_ori02( ori02 ), .pixel_ori03( ori03 ),.pixel_ori10( ori10 ), .pixel_ori11( ori11 ), .pixel_ori12( ori12 ), .pixel_ori13( ori13 ),.pixel_ori20( ori20 ), .pixel_ori21( ori21 ), .pixel_ori22( ori22 ), .pixel_ori23( ori23 ),.pixel_ori30( ori30 ), .pixel_ori31( ori31 ), .pixel_ori32( ori32 ), .pixel_ori33( ori33 ),

输出的残差信号是pixel_res00_o,这个信号是打一拍之后的赋值,打一拍之前的赋值关系是:

assign pixel_res00 = {1'b0,pixel_ori00} - {1'b0,pixel_pred00[`BIT_DEPTH-1:0]};
assign pixel_res01 = {1'b0,pixel_ori01} - {1'b0,pixel_pred01[`BIT_DEPTH-1:0]};
assign pixel_res02 = {1'b0,pixel_ori02} - {1'b0,pixel_pred02[`BIT_DEPTH-1:0]};
assign pixel_res03 = {1'b0,pixel_ori03} - {1'b0,pixel_pred03[`BIT_DEPTH-1:0]};
assign pixel_res10 = {1'b0,pixel_ori10} - {1'b0,pixel_pred10[`BIT_DEPTH-1:0]};
assign pixel_res11 = {1'b0,pixel_ori11} - {1'b0,pixel_pred11[`BIT_DEPTH-1:0]};
assign pixel_res12 = {1'b0,pixel_ori12} - {1'b0,pixel_pred12[`BIT_DEPTH-1:0]};
assign pixel_res13 = {1'b0,pixel_ori13} - {1'b0,pixel_pred13[`BIT_DEPTH-1:0]};
assign pixel_res20 = {1'b0,pixel_ori20} - {1'b0,pixel_pred20[`BIT_DEPTH-1:0]};
assign pixel_res21 = {1'b0,pixel_ori21} - {1'b0,pixel_pred21[`BIT_DEPTH-1:0]};
assign pixel_res22 = {1'b0,pixel_ori22} - {1'b0,pixel_pred22[`BIT_DEPTH-1:0]};
assign pixel_res23 = {1'b0,pixel_ori23} - {1'b0,pixel_pred23[`BIT_DEPTH-1:0]};
assign pixel_res30 = {1'b0,pixel_ori30} - {1'b0,pixel_pred30[`BIT_DEPTH-1:0]};
assign pixel_res31 = {1'b0,pixel_ori31} - {1'b0,pixel_pred31[`BIT_DEPTH-1:0]};
assign pixel_res32 = {1'b0,pixel_ori32} - {1'b0,pixel_pred32[`BIT_DEPTH-1:0]};
assign pixel_res33 = {1'b0,pixel_ori33} - {1'b0,pixel_pred33[`BIT_DEPTH-1:0]};

其中pixel_ori00就是输入的原始信号,那个pixel_pred00是什么呢?
可以看到,这个变量是通过一个case来赋值的:

always @(*)begincase(curr_mode)//0INTRA4x4_V   :beginpixel_pred00=ref00_t; pixel_pred01=ref01_t; pixel_pred02=ref02_t; pixel_pred03=ref03_t;pixel_pred10=ref00_t; pixel_pred11=ref01_t; pixel_pred12=ref02_t; pixel_pred13=ref03_t;pixel_pred20=ref00_t; pixel_pred21=ref01_t; pixel_pred22=ref02_t; pixel_pred23=ref03_t;pixel_pred30=ref00_t; pixel_pred31=ref01_t; pixel_pred32=ref02_t; pixel_pred33=ref03_t;

控制状态的变量为curr_mode,总共有9中情况,加上一个默认情况(全0)。这样就很清晰了,对应的就是9种预测模式:

垂直模式INTRA4x4_V

pixel_pred00=ref00_t; pixel_pred01=ref01_t; pixel_pred02=ref02_t; pixel_pred03=ref03_t;
pixel_pred10=ref00_t; pixel_pred11=ref01_t; pixel_pred12=ref02_t; pixel_pred13=ref03_t;
pixel_pred20=ref00_t; pixel_pred21=ref01_t; pixel_pred22=ref02_t; pixel_pred23=ref03_t;
pixel_pred30=ref00_t; pixel_pred31=ref01_t; pixel_pred32=ref02_t; pixel_pred33=ref03_t;


ABCD分别对应ref00_t/ref01_t/ref02_t/ref03_t

水平模式INTRA4x4_H

pixel_pred00=ref00_l; pixel_pred01=ref00_l; pixel_pred02=ref00_l; pixel_pred03=ref00_l;
pixel_pred10=ref01_l; pixel_pred11=ref01_l; pixel_pred12=ref01_l; pixel_pred13=ref01_l;
pixel_pred20=ref02_l; pixel_pred21=ref02_l; pixel_pred22=ref02_l; pixel_pred23=ref02_l;
pixel_pred30=ref03_l; pixel_pred31=ref03_l; pixel_pred32=ref03_l; pixel_pred33=ref03_l;


IJKL分别对应ref00_l/ref01_l/ref02_l/ref03_l

直流模式INTRA4x4_DC

 if(blk_avail[3]&&blk_avail[2])beginpixel_pred00=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred01=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred02=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred03=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred10=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred11=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred12=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred13=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred20=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred21=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred22=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred23=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred30=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred31=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred32=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;pixel_pred33=(ref00_t+ref01_t+ref02_t+ref03_t+ref00_l+ref01_l+ref02_l+ref03_l+3'd4)>>3;endelse if(blk_avail[3])beginpixel_pred00=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred01=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred02=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred03=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred10=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred11=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred12=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred13=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred20=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred21=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred22=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred23=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred30=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred31=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred32=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;pixel_pred33=(ref00_l+ref01_l+ref02_l+ref03_l+2'd2)>>2;endelse if(blk_avail[1])beginpixel_pred00=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred01=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred02=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred03=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred10=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred11=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred12=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred13=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred20=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred21=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred22=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred23=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred30=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred31=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred32=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;pixel_pred33=(ref00_t+ref01_t+ref02_t+ref03_t+2'd2)>>2;endelse beginpixel_pred00=8'd128;pixel_pred01=8'd128;pixel_pred02=8'd128;pixel_pred03=8'd128;pixel_pred10=8'd128;pixel_pred11=8'd128;pixel_pred12=8'd128;pixel_pred13=8'd128;pixel_pred20=8'd128;pixel_pred21=8'd128;pixel_pred22=8'd128;pixel_pred23=8'd128;pixel_pred30=8'd128;pixel_pred31=8'd128;pixel_pred32=8'd128;pixel_pred33=8'd128;end
end

看起来很长哈哈哈哈。

这个指示信号intra_4x4_ctrl来源于intra_4x4_ctrl模块,官方注释是4x4 block top, left, top_left, top_right available info.是四个信号的组合

assign   blk_avail       = {blk_lf_avail,blk_tl_avail,blk_tp_avail,blk_tr_avail};

我觉得可以理解为,如果前两位为1,就取水平和垂直两个方向的均值,如果只有最高位为1,就取水平方向的均值,如果只有次高位为1,就取垂直方向的均值。
呼呼~先码到这里,剩下的写在后面的文章里罗
加油鸭!ヾ(◍°∇°◍)ノ゙

H.264视频编解码的FPGA源码分析(二)帧内预测1相关推荐

  1. H.264视频编解码的FPGA源码分析(一)输入数据分析

    目录 概要 输入数据 宏块 概要 本文的源码基于复旦大学的开源芯片-开源H.265/H.264视频编码器项目,本文的工作主要是在梳理源码的同时学习H.264视频编解码的原理及其硬件实现. 输入数据 C ...

  2. 【H.264/AVC视频编解码技术详解】十七:帧内预测编码的预测实现方法

    <H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行 ...

  3. H.264视频编解码的代码移植和优化

    基于DSP系统开发的视频编解码系统,国内几乎都是走的移植,优化的路线,并且移植的代码,都是开源的.毕竟花费大量的人力,物力去开发一套自己的代码,并不见得比一些成熟的开源代码效率更高,健壮性更好.更何况 ...

  4. 数据压缩12 | 实验8 | H.264视频编解码

    目录 一.实验准备 1. H.264编码过程 2. 调试和编码(参考JM Reference Software Manual (JVT-AE010)) 3. 编码参数(参考JM Reference S ...

  5. 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准

    一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...

  6. 解析H.264视频编解码DSP实现与优化

    引言 基于互联网的数字视频产业前景看好,而3G的规模部署,也会推动移动视频通信成为现实.但数字化后的视频图像具有数据海量性,给图像的存储和传输造成较大的困难.数字视频产业,是指数字内容中以数字视频形态 ...

  7. H.264及编解码调试

    H.264及编解码调试 H.264是国际标准化组织(ISO)和国际电信联盟(ITU)在2002年12月共同提出的继MPEG-4之后的新一代数字视频压缩格式,其具有更高的编码效率,并注重对移动和IP网络 ...

  8. AIR 3实现iOS下对H.264视频硬件解码

    本帖最后由 nextria 于 2011-10-9 11:27 编辑 在此之前,AIR开发的应用程序在iOS下是不可能实现对H.264视频硬解码的, 也许是以一个多比特率的方式传送. 我知道,是吧? ...

  9. WebRTC[1]-WebRTC中h264解码过程的源码分析

    目录 前言 正文 <WebRTC工作原理精讲>系列-总览_liuzhen007的专栏-CSDN博客_webrtc 原理前言欢迎大家订阅Data-Mining 的<WebRTC工作原理 ...

最新文章

  1. mysql图形化及命令行操作用户权限
  2. “中国诺奖”2021未来科学大奖公布:袁国勇、裴伟士、张杰、施敏获奖,总奖金300万美元...
  3. Linux下使用system()函数一定要谨慎
  4. 清理mysql创建的游戏_Linux定时清理游戏log及mysql定时任务删除游戏日志数据的步骤...
  5. OpenCV中XML文件和YAML文件的读写
  6. linux 查看服务器网络连接,1.3.2 查看Linux服务器的网络连接(2)
  7. android释放焦点_Android videoview抢占焦点的处理方法
  8. jq checked 设置问题
  9. 滴滴人脸识别申诉照片怎么拍_涅槃乐队Nevermind封面照片是怎么拍出来的?
  10. ArcGIS Javascript API 加载高德在线地图扩展
  11. 设计灵感|展览海报如何排版?好的作品给你灵感
  12. 单位阶跃信号是周期信号吗_直流散热风扇的信号你知道如何控制吗?
  13. Springboot 默认加载文件(可直接访问、不可直接访问)是出现的问题
  14. 全国重点城市建筑物矢量数据合集二(Shp格式+带高度)
  15. winform开发框架介绍
  16. 上位机和下位机基础概念
  17. 一文读懂:DNA甲基化的作用及各种高通量检测方法比较
  18. Python - turtle画图库 临摹粉色花卉卡片
  19. openwrt-wps功能的实现(一)
  20. Unity2D 简易2D地图 —— 地图的显示

热门文章

  1. 7-13 统计工龄 (20 分)
  2. 前端 之 Vue初试
  3. 简述计算机噪音解决方法,电脑噪音很烦?教你几招解决
  4. 5G无线技术(笔记)
  5. 打不开计算机鼠标一直转,鼠标一直转圈浏览器也打不开怎么回事
  6. 哈佛大学开放课程:《公正:该如何做是好?》第3课
  7. 【闲聊杂谈】深挖IO
  8. 买了诺基亚又不待见他,微软图啥?
  9. java中缀转后缀_java实现中缀表达式转后缀的方法
  10. RGB图片像素点随机化——Matlab实现