macroblock.c
来自「h.264标准和jm」· C语言 代码 · 共 1,891 行 · 第 1/5 页
C
1,891 行
{
ref_idx = enc_picture->ref_idx[LIST_0+pred_dir][pix_c_x>>1][pix_c_y>>1];
mvb = mv [(i-img->pix_c_x)>>1][(j-img_pic_c_y)>>1][refframe][blocktype];
ii = (i<<s1) + mvb[0];
jj = (j<<s1) + mvb[1];
//SW
/*
if (!((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field)))
j1=(img->pix_c_y+jj+joff)*f1+mv_array[if1][jf][1];
else
{
if (img->current_mb_nr%2 == 0)
j1=(img->pix_c_y)/2*f1 + (jj+joff)*f1+mv_array[if1][jf][1];
else
j1=(img->pix_c_y-8)/2*f1 + (jj+joff)*f1 +mv_array[if1][jf][1];
}
*/
if (ref_idx!=-1)
jj += list[ref_idx]->chroma_vector_adjustment;
else
{
if (img->type!= I_SLICE)
jj += list[0]->chroma_vector_adjustment;
}
ii0 = max (0, min (img->width_cr -1, ii>>s1 ));
jj0 = max (0, min (img->height_cr/scale-1, jj>>s1 )); // For MB level field/frame -- scale chroma height by 2
ii1 = max (0, min (img->width_cr -1, (ii+f2)>>s1));
jj1 = max (0, min (img->height_cr/scale-1, (jj+f2)>>s1));
if1 = (ii&f2); if0 = f1-if1;
jf1 = (jj&f2); jf0 = f1-jf1;
*mpred++ = (if0 * jf0 * refimage[jj0][ii0] +
if1 * jf0 * refimage[jj0][ii1] +
if0 * jf1 * refimage[jj1][ii0] +
if1 * jf1 * refimage[jj1][ii1] + f4) / f3;
}
}
/*!
************************************************************************
* \brief
* Predict an intra chroma 4x4 block
************************************************************************
*/
void IntraChromaPrediction4x4 (int uv, // <-- colour component
int block_x, // <-- relative horizontal block coordinate of 4x4 block
int block_y) // <-- relative vertical block coordinate of 4x4 block
{
int mode = img->mb_data[img->current_mb_nr].c_ipred_mode;
int i, j;
//===== prediction =====
for (j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++)
{
img->mpr[i][j] = img->mprr_c[uv][mode][i][j];
}
}
/*!
************************************************************************
* \brief
* Predict one chroma 4x4 block
************************************************************************
*/
void
ChromaPrediction4x4 (int uv, // <-- colour component
int block_x, // <-- relative horizontal block coordinate of 4x4 block
int block_y, // <-- relative vertical block coordinate of 4x4 block
int fw_mode, // <-- forward prediction mode (1-7, 0=DIRECT if bw_mode=0)
int bw_mode, // <-- backward prediction mode (1-7, 0=DIRECT if fw_mode=0)
int fw_ref_frame, // <-- reference frame for forward prediction (if (<0) -> intra prediction)
int bw_ref_frame) // <-- reference frame for backward prediction
{
static int fw_pred[16];
static int bw_pred[16];
int i, j;
int block_x4 = block_x+4;
int block_y4 = block_y+4;
int pic_pix_x = img->pix_c_x + block_x;
int pic_pix_y = img->pix_c_y + block_y;
int* fpred = fw_pred;
int* bpred = bw_pred;
int direct = (fw_mode == 0 && bw_mode == 0 && (img->type == B_SLICE));
int skipped = (fw_mode == 0 && bw_mode == 0 && (img->type != B_SLICE));
int***** fmv_array = img->all_mv;
int***** bmv_array = img->all_bmv;
int fw_ref_idx, bw_ref_idx;
int apply_weights = ( (input->WeightedPrediction && (img->type == P_SLICE||img->type == SP_SLICE)) ||
(input->WeightedBiprediction && (img->type == B_SLICE)));
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
pic_pix_y = img->field_pix_c_y + block_y;
if(img->top_field)
{
fmv_array = img->all_mv_top;
bmv_array = img->all_bmv_top;
}
else
{
fmv_array = img->all_mv_bot;
bmv_array = img->all_bmv_bot;
}
}
direct_mode = direct && input->direct_type==0;
//===== INTRA PREDICTION =====
if (fw_ref_frame < 0)
{
IntraChromaPrediction4x4 (uv, block_x, block_y);
return;
}
if (input->direct_type && direct)
{
fw_ref_frame = fwdir_refFrArr[pic_pix_y/2][pic_pix_x/2];
bw_ref_frame = bwdir_refFrArr[pic_pix_y/2][pic_pix_x/2];
}
if (img->type == B_SLICE && img->nal_reference_idc>0)
{
fw_ref_idx = fw_ref_frame;
bw_ref_idx = (bw_ref_frame < 2) ? 1-bw_ref_frame : bw_ref_frame;
}
else
{
fw_ref_idx = fw_ref_frame;
bw_ref_idx = bw_ref_frame;
}
//===== 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 == 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_pi
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?