📄 b_picture.c
字号:
} forward_MV->Mode = MODE_INTER; backward_MV->Mode = MODE_INTER; break; case B_INTRA_PREDICTION: /* 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; forward_MV->Mode = MODE_INTRA; backward_MV->Mode = MODE_INTRA; break; default: fprintf (stderr, "Illegal scalable prediction type in MB_Recon_True_B (pred.c)\n"); exit (-1); } free (backward_pred); free (forward_pred); free (bidir_pred); free (direct_f_pred); free (direct_b_pred); free (direct_pred); return pred_error;}/********************************************************************** * * Name: MB_Recon_True_B * Description: Reconstructs MB after quantization for true B frames * * Input: pointers to decoded residual, 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 reconstructed MB data after motion compensation * Side effects: allocates memory to MB_structure * * Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *MB_Recon_True_B (PictImage * prev_image, unsigned char *prev_ipol, MB_Structure *diff, PictImage * next_image, unsigned char *next_ipol, int x_curr, int y_curr, MotionVector * MV[7][MBR + 1][MBC + 2], MotionVector * Direct_MV[5][MBR][MBC], int TRB, int prediction_type, int RTYPE){ MB_Structure *bidir_forward = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *bidir_backward = (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 *recon_data = (MB_Structure *) malloc (sizeof (MB_Structure)); MotionVector *forward_MV, *backward_MV, *direct_MV[5]; int dxf, dyf, dxb, dyb; int i, j, k, xvec, yvec, mvx, mvy; direct_MV[0] = Direct_MV[0][y_curr / MB_SIZE][x_curr / MB_SIZE]; direct_MV[1] = Direct_MV[1][y_curr / MB_SIZE][x_curr / MB_SIZE]; direct_MV[2] = Direct_MV[2][y_curr / MB_SIZE][x_curr / MB_SIZE]; direct_MV[3] = Direct_MV[3][y_curr / MB_SIZE][x_curr / MB_SIZE]; direct_MV[4] = Direct_MV[4][y_curr / MB_SIZE][x_curr / MB_SIZE]; switch (prediction_type) { case B_DIRECT_PREDICTION: /* 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_curr, y_curr, direct_MV[1], &direct_f_pred->lum[0][0], TRB, 8, 0); FindForwLumPredDirectTrueB (prev_ipol, x_curr, y_curr, direct_MV[2], &direct_f_pred->lum[0][8], TRB, 8, 1); FindForwLumPredDirectTrueB (prev_ipol, x_curr, y_curr, direct_MV[3], &direct_f_pred->lum[8][0], TRB, 8, 2); FindForwLumPredDirectTrueB (prev_ipol, x_curr, y_curr, direct_MV[4], &direct_f_pred->lum[8][8], TRB, 8, 3); FindBackwLumPredDirectTrueB (next_ipol, x_curr, y_curr, direct_MV[1], &direct_b_pred->lum[0][0], TRB, 8, 0); FindBackwLumPredDirectTrueB (next_ipol, x_curr, y_curr, direct_MV[2], &direct_b_pred->lum[0][8], TRB, 8, 1); FindBackwLumPredDirectTrueB (next_ipol, x_curr, y_curr, direct_MV[3], &direct_b_pred->lum[8][0], TRB, 8, 2); FindBackwLumPredDirectTrueB (next_ipol, x_curr, y_curr, direct_MV[4], &direct_b_pred->lum[8][8], TRB, 8, 3); /* 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 */ dxf = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2); dyf = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2); /* Predict B as if P. */ FindChromBlock_P (x_curr, y_curr, dxf, dyf, 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 */ dxb = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2); dyb = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2); /* Predict B as if P. */ FindChromBlock_P (x_curr, y_curr, dxb, dyb, next_image, direct_b_pred, RTYPE); } else { FindForwLumPredDirectTrueB (prev_ipol, x_curr, y_curr, direct_MV[0], &direct_f_pred->lum[0][0], TRB, 16, 0); FindBackwLumPredDirectTrueB (next_ipol, x_curr, y_curr, direct_MV[0], &direct_b_pred->lum[0][0], TRB, 16, 0); 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). */ dxf = TRB * mvx / TRP; dyf = TRB * mvy / TRP; dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1); dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1); /* Predict B as if P. */ FindChromBlock_P (x_curr, y_curr, dxf, dyf, prev_image, direct_f_pred, RTYPE); /* Translate MV to chrominance-resolution (downsampled). */ dxb = (TRB - TRP) * mvx / TRP; dyb = (TRB - TRP) * mvy / TRP; dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1); dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1); /* Predict B as if P. */ FindChromBlock_P (x_curr, y_curr, dxb, dyb, next_image, direct_b_pred, RTYPE); } for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { diff->lum[j][i] += (direct_f_pred->lum[j][i] + direct_b_pred->lum[j][i]) / 2; } } for (j = 0; j < MB_SIZE >> 1; j++) { for (i = 0; i < MB_SIZE >> 1; i++) { diff->Cr[j][i] += (direct_f_pred->Cr[j][i] + direct_b_pred->Cr[j][i]) / 2; diff->Cb[j][i] += (direct_f_pred->Cb[j][i] + direct_b_pred->Cb[j][i]) / 2; } } break; case B_FORWARD_PREDICTION: forward_MV = MV[0][y_curr / MB_SIZE + 1][x_curr / MB_SIZE + 1]; if (forward_MV->Mode == MODE_INTER || forward_MV->Mode == MODE_INTER_Q) { /* Inter 16x16 */ ReconLumBlock_P (x_curr, y_curr, forward_MV, prev_ipol, &diff->lum[0][0], 16, 0); dxf = 2 * forward_MV->x + forward_MV->x_half; dyf = 2 * forward_MV->y + forward_MV->y_half; dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1); dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1); ReconChromBlock_P (x_curr, y_curr, dxf, dyf, prev_image, diff, RTYPE); } break; case B_BACKWARD_PREDICTION: backward_MV = MV[5][y_curr / MB_SIZE + 1][x_curr / MB_SIZE + 1]; if (backward_MV->Mode == MODE_INTER || backward_MV->Mode == MODE_INTER_Q) { /* Inter 16x16 */ ReconLumBlock_P (x_curr, y_curr, backward_MV, next_ipol, &diff->lum[0][0], 16, 0); dxb = 2 * backward_MV->x + backward_MV->x_half; dyb = 2 * backward_MV->y + backward_MV->y_half; dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1); dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1); ReconChromBlock_P (x_curr, y_curr, dxb, dyb, next_image, diff, RTYPE); } break; case B_BIDIRECTIONAL_PREDICTION: forward_MV = MV[0][y_curr / MB_SIZE + 1][x_curr / MB_SIZE + 1]; backward_MV = MV[5][y_curr / MB_SIZE + 1][x_curr / MB_SIZE + 1]; if ((forward_MV->Mode == MODE_INTER || forward_MV->Mode == MODE_INTER_Q) || (backward_MV->Mode == MODE_INTER || backward_MV->Mode == MODE_INTER_Q)) { /* Forward prediction. */ FindPred (x_curr, y_curr, forward_MV, prev_ipol, &bidir_forward->lum[0][0], 16, 0); /* Backward prediction. */ FindPred (x_curr, y_curr, backward_MV, next_ipol, &bidir_backward->lum[0][0], 16, 0); for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { diff->lum[j][i] += (bidir_forward->lum[j][i] + bidir_backward->lum[j][i]) / 2; } } dxf = 2 * forward_MV->x + forward_MV->x_half; dyf = 2 * forward_MV->y + forward_MV->y_half; dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1); dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1); dxb = 2 * backward_MV->x + backward_MV->x_half; dyb = 2 * backward_MV->y + backward_MV->y_half; dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1); dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1); FindChromBlock_P (x_curr, y_curr, dxf, dyf, prev_image, bidir_forward, RTYPE); FindChromBlock_P (x_curr, y_curr, dxb, dyb, next_image, bidir_backward, RTYPE); for (j = 0; j < MB_SIZE / 2; j++) { for (i = 0; i < MB_SIZE / 2; i++) { diff->Cr[j][i] += (bidir_forward->Cr[j][i] + bidir_backward->Cr[j][i]) / 2; diff->Cb[j][i] += (bidir_forward->Cb[j][i] + bidir_backward->Cb[j][i]) / 2; } } } break; case B_INTRA_PREDICTION: break; default: fprintf (stderr, "Illegal scalable prediction type in MB_Recon_True_B (pred.c)\n"); exit (-1); break; } memcpy (recon_data, diff, sizeof (MB_Structure)); free (bidir_forward); free (bidir_backward); free (direct_f_pred); free (direct_b_pred); return recon_data;}/********************************************************************** * * Name: FindForwLumPredDirectTrueB * Description: Finds the forward luma prediction in true B frame * pred. * * Input: pointer to prev. ipol frame, current positon, * MV structure and pred. structure to fill * * Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca * ***********************************************************************/void FindForwLumPredDirectTrueB (unsigned char *prev_ipol, int x_curr, int y_curr, MotionVector * fr, int *pred, int TRB, int bs, int comp){ int i, j; int xvec, yvec, lx; lx = (mv_outside_frame ? pels + (long_vectors ? 64 : 32) : pels); /* Luma */ xvec = (TRB) * (2 * fr->x + fr->x_half) / TRP; yvec = (TRB) * (2 * fr->y + fr->y_half) / TRP; x_curr += ((comp & 1) << 3); y_curr += ((comp & 2) << 2); for (j = 0; j < bs; j++) { for (i = 0; i < bs; i++) { *(pred + i + j * 16) = *(prev_ipol + (i + x_curr) * 2 + xvec + ((j + y_curr) * 2 + yvec) * lx * 2); } } return;}/********************************************************************** * * Name: FindBackwLumPredDirectTrueB * Description: Finds the backward luma prediction in true B frame * pred. * * Input: pointer to next ipol frame, current positon, * MV structure and pred. structure to fill * * Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca * ***********************************************************************/void FindBackwLumPredDirectTrueB (unsigned char *next_ipol, int x_curr, int y_curr, MotionVector * fr, int *pred, int TRB, int bs, int comp){ int i, j; int xvec, yvec, mvx, mvy, lx; lx = (mv_outside_frame ? pels + (long_vectors ? 64 : 32) : pels); /* Luma */ mvx = 2 * fr->x + fr->x_half; mvy = 2 * fr->y + fr->y_half; xvec = (TRB - TRP) * mvx / TRP; yvec = (TRB - TRP) * mvy / TRP; x_curr += ((comp & 1) << 3); y_curr += ((comp & 2) << 2); for (j = 0; j < bs; j++) { for (i = 0; i < bs; i++) { *(pred + i + j * 16) = *(next_ipol + (i + x_curr) * 2 + xvec + ((j + y_curr) * 2 + yvec) * lx * 2); } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -