📄 b_picture.c
字号:
{ free(store_coeff); free(store_rcoeff); } if (advanced_temporarily_off) { overlapping_MC = ON; adv_pred = ON; use_4mv = ON; advanced_temporarily_off = NO; } return;}/*********************************************************************** * * Name: Predict_True_B * Description: Predicts B macroblock in true B frame prediction * * Input: pointers to current frame, previous recon. previous * interpolated, next recon, next interpolated, * pos. in image, MV data, Direct Mode MV data, * TRB for Direct Mode prediction, and MB prediction type. * Returns: pointer to differential MB data after prediction * Side effects: * * Date: 970831 Author: Michael Gallant ---mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *Predict_True_B (PictImage * curr_image, PictImage * prev_image, unsigned char *prev_ipol, PictImage * next_image, unsigned char *next_ipol, MB_Structure * pred_macroblock, int x, int y, MotionVector * MV[7][MBR + 1][MBC + 2], MotionVector * Direct_MV[5][MBR][MBC], int TRB, int *prediction_type, int *mode, int RTYPE){ int curr[16][16]; MB_Structure *forward_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *backward_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *direct_f_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *direct_b_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *direct_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *bidir_pred = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *pred_error = (MB_Structure *) malloc (sizeof (MB_Structure)); MotionVector *forward_MV, *backward_MV, *direct_MV[5]; int SADbackw, SADbidir, SADforw, SADdirect, SADmin; int dx, dy, xmb, ymb, i, j, k; int xvec, yvec, mvx, mvy; xmb = x / MB_SIZE + 1; ymb = y / MB_SIZE + 1; forward_MV = MV[0][ymb][xmb]; backward_MV = MV[5][ymb][xmb]; direct_MV[0] = Direct_MV[0][ymb - 1][xmb - 1]; direct_MV[1] = Direct_MV[1][ymb - 1][xmb - 1]; direct_MV[2] = Direct_MV[2][ymb - 1][xmb - 1]; direct_MV[3] = Direct_MV[3][ymb - 1][xmb - 1]; direct_MV[4] = Direct_MV[4][ymb - 1][xmb - 1]; /* Find MB in current image */ FindMB (x, y, curr_image->lum, curr); /* Forward prediction. */ FindPred (x, y, forward_MV, prev_ipol, &forward_pred->lum[0][0], 16, 0); /* Backward prediction. */ FindPred (x, y, backward_MV, next_ipol, &backward_pred->lum[0][0], 16, 0); /* Direct prediction, forward and backward components. */ if (direct_MV[0]->Mode == MODE_INTER4V || direct_MV[0]->Mode == MODE_INTER4V_Q) { /* Mode INTER4V */ FindForwLumPredDirectTrueB (prev_ipol, x, y, direct_MV[1], &direct_f_pred->lum[0][0], TRB, 8, 0); FindForwLumPredDirectTrueB (prev_ipol, x, y, direct_MV[2], &direct_f_pred->lum[0][8], TRB, 8, 1); FindForwLumPredDirectTrueB (prev_ipol, x, y, direct_MV[3], &direct_f_pred->lum[8][0], TRB, 8, 2); FindForwLumPredDirectTrueB (prev_ipol, x, y, direct_MV[4], &direct_f_pred->lum[8][8], TRB, 8, 3); FindBackwLumPredDirectTrueB (next_ipol, x, y, direct_MV[1], &direct_b_pred->lum[0][0], TRB, 8, 0); FindBackwLumPredDirectTrueB (next_ipol, x, y, direct_MV[2], &direct_b_pred->lum[0][8], TRB, 8, 1); FindBackwLumPredDirectTrueB (next_ipol, x, y, direct_MV[3], &direct_b_pred->lum[8][0], TRB, 8, 2); FindBackwLumPredDirectTrueB (next_ipol, x, y, direct_MV[4], &direct_b_pred->lum[8][8], TRB, 8, 3); } else { FindForwLumPredDirectTrueB (prev_ipol, x, y, direct_MV[0], &direct_f_pred->lum[0][0], TRB, 16, 0); FindBackwLumPredDirectTrueB (next_ipol, x, y, direct_MV[0], &direct_b_pred->lum[0][0], TRB, 16, 0); } for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { /* Bidirectional prediction. */ bidir_pred->lum[j][i] = (forward_pred->lum[j][i] + backward_pred->lum[j][i]) / 2; /* Direct prediction. */ direct_pred->lum[j][i] = (direct_f_pred->lum[j][i] + direct_b_pred->lum[j][i]) / 2; } } SADforw = SAD_MB_integer (&curr[0][0], &forward_pred->lum[0][0], 16, INT_MAX); SADforw -= 50; SADbackw = SAD_MB_integer (&curr[0][0], &backward_pred->lum[0][0], 16, INT_MAX); SADdirect = SAD_MB_integer (&curr[0][0], &direct_pred->lum[0][0], 16, INT_MAX); SADdirect -= 100; SADbidir = SAD_MB_integer (&curr[0][0], &bidir_pred->lum[0][0], 16, INT_MAX); SADbidir += 75; /* Prediction direction decision. */ if ((SADdirect <= SADforw) && (SADdirect <= SADbackw) && (SADdirect <= SADbidir)) { *prediction_type = B_DIRECT_PREDICTION; SADmin = SADdirect; } else if ((SADforw < SADdirect) && (SADforw <= SADbackw) && (SADforw <= SADbidir)) { *prediction_type = B_FORWARD_PREDICTION; SADmin = SADforw; } else if ((SADbackw < SADdirect) && (SADbackw < SADforw) && (SADbackw <= SADbidir)) { *prediction_type = B_BACKWARD_PREDICTION; SADmin = SADbackw; } else { *prediction_type = B_BIDIRECTIONAL_PREDICTION; SADmin = SADbidir; } *(mode) = ChooseMode( curr_image->lum, x, y, SADmin); if (MODE_INTRA == *(mode) || MODE_INTRA_Q == *(mode)) { *prediction_type = B_INTRA_PREDICTION; } switch (*prediction_type) { case B_FORWARD_PREDICTION: /* Translate MV to chrominance-resolution (downsampled). */ dx = 2 * forward_MV->x + forward_MV->x_half; dy = 2 * forward_MV->y + forward_MV->y_half; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ DoPredChrom_P (x, y, dx, dy, curr_image, prev_image, forward_pred, pred_error, RTYPE); for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) - forward_pred->lum[j][i]; pred_macroblock->lum[j][i] = forward_pred->lum[j][i]; } } for (j = 0; j < MB_SIZE >> 1; j++) { for (i = 0; i < MB_SIZE >> 1; i++) { pred_macroblock->Cr[j][i] = forward_pred->Cr[j][i]; pred_macroblock->Cb[j][i] = forward_pred->Cb[j][i]; } } forward_MV->Mode = MODE_INTER; backward_MV->Mode = MODE_INTRA; /* Set backward MV data to 0 for future MV prediction. */ backward_MV->x = backward_MV->x_half = 0; backward_MV->y = backward_MV->y_half = 0; break; case B_BACKWARD_PREDICTION: /* Translate MV to chrominance-resolution (downsampled). */ dx = 2 * backward_MV->x + backward_MV->x_half; dy = 2 * backward_MV->y + backward_MV->y_half; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ DoPredChrom_P (x, y, dx, dy, curr_image, next_image, backward_pred, pred_error, RTYPE); for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) - backward_pred->lum[j][i]; pred_macroblock->lum[j][i] = backward_pred->lum[j][i]; } } for (j = 0; j < MB_SIZE >> 1; j++) { for (i = 0; i < MB_SIZE >> 1; i++) { pred_macroblock->Cr[j][i] = backward_pred->Cr[j][i]; pred_macroblock->Cb[j][i] = backward_pred->Cb[j][i]; } } forward_MV->Mode = MODE_INTRA; backward_MV->Mode = MODE_INTER; /* Set forward MV data to 0 for future MV prediction. */ forward_MV->x = forward_MV->x_half = 0; forward_MV->y = forward_MV->y_half = 0; break; case B_DIRECT_PREDICTION: /* Direct prediction, forward and backward components. */ if (direct_MV[0]->Mode == MODE_INTER4V || direct_MV[0]->Mode == MODE_INTER4V_Q) { /* chroma vectors are sum of B luma vectors divided and rounded */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { xvec += TRB * (2 * direct_MV[k]->x + direct_MV[k]->x_half) / TRP; yvec += TRB * (2 * direct_MV[k]->y + direct_MV[k]->y_half) / TRP; } /* round values according to TABLE 16/H.263 */ dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2); dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2); /* Predict B as if P. */ FindChromBlock_P (x, y, dx, dy, prev_image, direct_f_pred, RTYPE); /* chroma vectors are sum of B luma vectors divided and rounded */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { mvx = 2 * direct_MV[k]->x + direct_MV[k]->x_half; mvy = 2 * direct_MV[k]->y + direct_MV[k]->y_half; xvec += (TRB - TRP) * mvx / TRP; yvec += (TRB - TRP) * mvy / TRP; } /* round values according to TABLE 16/H.263 */ dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2); dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2); /* Predict B as if P. */ FindChromBlock_P (x, y, dx, dy, next_image, direct_b_pred, RTYPE); } else { mvx = 2 * direct_MV[0]->x + direct_MV[0]->x_half; mvy = 2 * direct_MV[0]->y + direct_MV[0]->y_half; /* Translate MV to chrominance-resolution (downsampled). */ dx = TRB * mvx / TRP; dy = TRB * mvy / TRP; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ FindChromBlock_P (x, y, dx, dy, prev_image, direct_f_pred, RTYPE); /* Translate MV to chrominance-resolution (downsampled). */ dx = (TRB - TRP) * mvx / TRP; dy = (TRB - TRP) * mvy / TRP; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ FindChromBlock_P (x, y, dx, dy, next_image, direct_b_pred, RTYPE); } for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) - direct_pred->lum[j][i]; pred_macroblock->lum[j][i] = direct_pred->lum[j][i]; } } for (j = 0; j < MB_SIZE >> 1; j++) { for (i = 0; i < MB_SIZE >> 1; i++) { pred_macroblock->Cr[j][i] = (direct_f_pred->Cr[j][i] + direct_b_pred->Cr[j][i]) / 2; pred_macroblock->Cb[j][i] = (direct_f_pred->Cb[j][i] + direct_b_pred->Cb[j][i]) / 2; pred_error->Cr[j][i] = *(curr_image->Cr + (x>>1) + i + ((y>>1) + j) * cpels) - pred_macroblock->Cr[j][i]; pred_error->Cb[j][i] = *(curr_image->Cb + (x>>1) + i + ((y>>1) + j) * cpels) - pred_macroblock->Cb[j][i]; } } forward_MV->Mode = MODE_INTER; backward_MV->Mode = MODE_INTER; /* Set forward MV data to 0 for future MV prediction. */ forward_MV->x = forward_MV->x_half = 0; forward_MV->y = forward_MV->y_half = 0; /* Set backward MV data to 0 for future MV prediction. */ backward_MV->x = backward_MV->x_half = 0; backward_MV->y = backward_MV->y_half = 0; break; case B_BIDIRECTIONAL_PREDICTION: /* Translate MV to chrominance-resolution (downsampled). */ dx = 2 * forward_MV->x + forward_MV->x_half; dy = 2 * forward_MV->y + forward_MV->y_half; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ DoPredChrom_P (x, y, dx, dy, curr_image, prev_image, forward_pred, pred_error, RTYPE); /* Translate MV to chrominance-resolution (downsampled). */ dx = 2 * backward_MV->x + backward_MV->x_half; dy = 2 * backward_MV->y + backward_MV->y_half; dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1); dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1); /* Predict B as if P. */ DoPredChrom_P (x, y, dx, dy, curr_image, next_image, backward_pred, pred_error, RTYPE); for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) - bidir_pred->lum[j][i]; pred_macroblock->lum[j][i] = bidir_pred->lum[j][i]; } } for (j = 0; j < MB_SIZE >> 1; j++) { for (i = 0; i < MB_SIZE >> 1; i++) { pred_macroblock->Cr[j][i] = (forward_pred->Cr[j][i] + backward_pred->Cr[j][i]) / 2; pred_macroblock->Cb[j][i] = (forward_pred->Cb[j][i] + backward_pred->Cb[j][i]) / 2; pred_error->Cr[j][i] = *(curr_image->Cr + (x>>1) + i + ((y>>1) + j) * cpels) - pred_macroblock->Cr[j][i]; pred_error->Cb[j][i] = *(curr_image->Cb + (x>>1) + i + ((y>>1) + j) * cpels) - pred_macroblock->Cb[j][i]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -