📄 h.264
字号:
//===== INTER PREDICTION =====
if (fw_mode || (direct && (!input->direct_type || fw_ref_frame!=-1)) || skipped)
{
OneComponentChromaPrediction4x4 (fw_pred, pic_pix_x, pic_pix_y, fmv_array , fw_ref_frame, fw_mode, uv);
}
if (bw_mode || (direct && (!input->direct_type || bw_ref_frame!=-1)))
{
//if (img->type == BS_IMG)
if (img->type == B_SLICE && img->nal_reference_idc>0)
OneComponentChromaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, bmv_array, bw_ref_frame, bw_mode, uv);
else
OneComponentChromaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, bmv_array, -1, bw_mode, uv);
}
if (apply_weights)
{
if (direct || (fw_mode && bw_mode))
{
if (direct && input->direct_type)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
if (fw_ref_frame==-1)
img->mpr[i][j] = clip1a(((wp_weight[1][bw_ref_idx][uv+1] * *bpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[1][bw_ref_idx][uv+1]);
else if (bw_ref_frame==-1)
img->mpr[i][j] = clip1a(((wp_weight[0][fw_ref_idx][uv+1] * *fpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[0][fw_ref_idx][uv+1]);
else
img->mpr[i][j] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++
+ 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1) );
}
else
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++
+ 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1));
}
else if (img->type == B_SLICE && img->nal_reference_idc>0)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++
+ 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1));
}
else if (fw_mode || skipped)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = clip1a(((wp_weight[0][fw_ref_idx][uv+1] * *fpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[0][fw_ref_idx][uv+1]);
}
else
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = clip1a(((wp_weight[1][bw_ref_idx][uv+1] * *bpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[1][bw_ref_idx][uv+1]);
}
}
else
{
if (direct || (fw_mode && bw_mode))
{
if (direct && input->direct_type)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
if (fw_ref_frame==-1)
img->mpr[i][j] = *bpred++;
else if (bw_ref_frame==-1)
img->mpr[i][j] = *fpred++;
else
img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2;
}
else
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2;
}
else if (img->type == B_SLICE && img->nal_reference_idc>0)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++)
img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2;
}
else if (fw_mode || skipped)
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++) img->mpr[i][j] = *fpred++;
}
else
{
for (j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++) img->mpr[i][j] = *bpred++;
}
}
}
/*!
************************************************************************
* \brief
* Chroma residual coding for an macroblock
************************************************************************
*/
void ChromaResidualCoding (int* cr_cbp)
{
int uv, block8, block_y, block_x, j, i;
int fw_mode, bw_mode, refframe;
int skipped = (img->mb_data[img->current_mb_nr].mb_type == 0 && (img->type == P_SLICE || img->type == SP_SLICE));
int incr = 1, offset = 0; // For MB level field/frame coding
int bw_ref;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
incr = 2; // increment every other field
if(!img->top_field)
offset = -7;
}
for (*cr_cbp=0, uv=0; uv<2; uv++)
{
//===== prediction of chrominance blocks ===d==
block8 = 0;
for (block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4, block8++)
{
SetModesAndRefframe (block8, &fw_mode, &bw_mode, &refframe, &bw_ref);
ChromaPrediction4x4 (uv, block_x, block_y, fw_mode, bw_mode, refframe, bw_ref);
}
// ==== set chroma residue to zero for skip Mode in SP frames
if (img->NoResidueDirect)
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
}
else
if (skipped && img->type==SP_SLICE)
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
img->m7[i][j] = 0;
}
else
if (skipped)
{
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
}
}
else
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
img->m7[i][j] = imgUV_org[uv][img->pix_c_y+(j*incr)+offset][img->pix_c_x+i] - img->mpr[i][j];
}
//===== DCT, Quantization, inverse Quantization, IDCT, and Reconstruction =====
//===== Call function for skip mode in SP frames to properly process frame ====
if (skipped && img->type==SP_SLICE)
{
*cr_cbp=dct_chroma_sp(uv,*cr_cbp);
}
else
if (!img->NoResidueDirect && !skipped)
{
if (img->type!=SP_SLICE || IS_INTRA (&img->mb_data[img->current_mb_nr]))
*cr_cbp=dct_chroma (uv,*cr_cbp);
else
*cr_cbp=dct_chroma_sp(uv,*cr_cbp);
}
}
//===== update currMB->cbp =====
img->mb_data[img->current_mb_nr].cbp += ((*cr_cbp)<<4);
}
/*!
************************************************************************
* \brief
* Predict an intra chroma 8x8 block
************************************************************************
*/
void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int s, s0, s1, s2, s3, i, j, k;
pel_t** image;
int block_x, block_y, b4;
int img_cx = img->pix_c_x;
int img_cy = img->pix_c_y;
int img_cx_1 = img->pix_c_x-1;
int img_cx_4 = img->pix_c_x+4;
int img_cy_1 = img->pix_c_y-1;
int img_cy_4 = img->pix_c_y+4;
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
int mb_available_left = (img_cx/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-1] .slice_nr);
int mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
int ih,iv;
int ib,ic,iaa;
int uv;
int hline[8], vline[8];
int mode;
int best_mode = DC_PRED_8; //just an initilaization here, should always be overwritten
int cost;
int min_cost;
int diff[16];
int left_avail;
PixelPos up; //!< pixel position p(0,-1)
PixelPos left[9]; //!< pixel positions p(-1, -1..8)
for (i=0;i<9;i++)
{
getNeighbour(mb_nr, -1 , i-1 , 0, &left[i]);
}
getNeighbour(mb_nr, 0 , -1 , 0, &up);
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
img_cy = img->field_pix_c_y;
img_cy_1 = img->field_pix_c_y-1;
img_cy_4 = img->field_pix_c_y+4;
mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
}
if(input->UseConstrainedIntraPred)
{
mb_available_up = up.available ? img->intra_block[up.mb_addr] : 0;
for (i=1, left_avail=1; i<9;i++)
mb_available_left &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
mb_available_up_left = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
}
if (mb_up)
*mb_up = mb_available_up;
if (mb_left)
*mb_left = mb_available_left;
if( mb_up_left )
*mb_up_left = mb_available_up_left;
// compute all chroma intra prediction modes for both U and V
for (uv=0; uv<2; uv++)
{
/* if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
if(img->top_field)
image = imgUV_top[uv];
else
image = imgUV_bot[uv];
}
else
*/
image = enc_picture->imgUV[uv];
// DC prediction
for (block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4)
{
s=128;
s0=s1=s2=s3=0;
//===== get prediction value =====
switch ((block_y>>1) + (block_x>>2))
{
case 0: //===== TOP LEFT =====
if (mb_available_up) for (i=0;i<4;i++) s0 += image[img_cy_1 ][img_cx +i];
if (mb_available_left) for (i=0;i<4;i++) s2 += image[img_cy +i][img_cx_1 ];
if (mb_available_up && mb_available_left) s = (s0+s2+4) >> 3;
else if (mb_available_up) s = (s0 +2) >> 2;
else if (mb_available_left) s = (s2 +2) >> 2;
break;
case 1: //===== TOP RIGHT =====
if (mb_available_up) for (i=0;i<4;i++) s1 += image[img_cy_1 ][img_cx_4+i];
else if (mb_available_left) for (i=0;i<4;i++) s2 += image[img_cy +i][img_cx_1 ];
if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left) s = (s2 +2) >> 2;
break;
case 2: //===== BOTTOM LEFT =====
if (mb_available_left) for (i=0;i<4;i++) s3 += image[img_cy_4+i][img_cx_1 ];
else if (mb_available_up) for (i=0;i<4;i++) s0 += image[img_cy_1 ][img_cx +i];
if (mb_available_left) s = (s3 +2) >> 2;
else if (mb_available_up) s = (s0 +2) >> 2;
break;
case 3: //===== BOTTOM RIGHT =====
if (mb_available_up) for (i=0;i<4;i++) s1 += image[img_cy_1 ][img_cx_4+i];
if (mb_available_left) for (i=0;i<4;i++) s3 += image[img_cy_4+i][img_cx_1 ];
if (mb_available_up && mb_available_left) s = (s1+s3+4) >> 3;
else if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left) s = (s3 +2) >> 2;
break;
}
//===== prediction =====
for (j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++)
{
img->mprr_c[uv][DC_PRED_8][i][j] = s;
}
}
// vertical prediction
if (mb_available_up)
{
for (i=0; i<8; i++)
hline[i] = image[img_cy_1][img_cx+i];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
}
// horizontal prediction
if (mb_available_left)
{
for (i=0; i<8; i++)
vline[i] = image[img_cy+i][img_cx_1];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j];
}
// plane prediction
if (mb_available_up_left)
{
ih = 4*(hline[7] - image[img_cy_1][img_cx_1]);
iv = 4*(vline[7] - image[img_cy_1][img_cx_1]);
for (i=1;i<4;i++)
{
ih += i*(hline[3+i] - hline[3-i]);
iv += i*(vline[3+i] - vline[3-i]);
}
ib=(17*ih+16)>>5;
ic=(17*iv+16)>>5;
iaa=16*(hline[7]+vline[7]);
for (j=0; j<8; j++)
for (i=0; i<8; i++)
img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
}
}
if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
{ // since ipredmodes could be overwritten => encoder-decoder-mismatches
// pick lowest cost prediction mode
min_cost = 1<<20;
for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
{
if ((mode==VERT_PRED_8 && !mb_available_up) ||
(mode==HOR_PRED_8 && !mb_available_left) ||
(mode==PLANE_8 && (!mb_available_left || !mb_available_up || !mb_available_up_left)))
continue;
cost = 0;
for (uv=0; uv<2; uv++
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -