?? pred.c
字號:
#include"sim.h"static int roundtab[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};/********************************************************************** * * 函數(shù)名:P幀圖像的預(yù)測 * 函數(shù)功能:P幀編碼宏塊的運(yùn)動預(yù)測編碼(普通模式和高級模式) * 函數(shù)輸入:curr_image:當(dāng)前幀圖像 * prev_image:上一幀圖像 * prev_ipol:上一幀內(nèi)插圖像 * x:宏塊的位置(水平方位)
* y:宏塊的位置(豎直方位)
* MV:運(yùn)動向量
* PB:運(yùn)動估計模式標(biāo)志
* 函數(shù)返回值:編碼宏塊數(shù)據(jù)的指針 ***********************************************************************/MB_Structure *Predict_P(PictImage *curr_image, PictImage *prev_image, unsigned char *prev_ipol, int x, int y, MotionVector *MV[6][MBR+1][MBC+2], int PB){ int m,n; int curr[16][16]; int pred[16][16]; MotionVector *fr0,*fr1,*fr2,*fr3,*fr4; int sum, dx, dy; int xmb, ymb; MB_Structure *pred_error = (MB_Structure *)malloc(sizeof(MB_Structure)); xmb = x/MB_SIZE+1; ymb = y/MB_SIZE+1; fr0 = MV[0][ymb][xmb]; fr1 = MV[1][ymb][xmb]; fr2 = MV[2][ymb][xmb]; fr3 = MV[3][ymb][xmb]; fr4 = MV[4][ymb][xmb]; /* 找到當(dāng)前幀的編碼宏塊 */ FindMB(x, y, curr_image->lum, curr); /* 利用半像素精度的運(yùn)動向量尋找預(yù)測值 */ if (advanced) { FindPredOBMC(x, y, MV, prev_ipol, &pred[0][0], 0, PB); FindPredOBMC(x, y, MV, prev_ipol, &pred[0][8], 1, PB); FindPredOBMC(x, y, MV, prev_ipol, &pred[8][0], 2, PB); FindPredOBMC(x, y, MV, prev_ipol, &pred[8][8], 3, PB); } else FindPred(x, y, fr0, prev_ipol, &pred[0][0], 16, 0); /* 實際運(yùn)動估計的預(yù)測 */ if (fr0->Mode == MODE_INTER || fr0->Mode == MODE_INTER_Q) { for (n = 0; n < MB_SIZE; n++) for (m = 0; m < MB_SIZE; m++) pred_error->lum[n][m] = (int)(curr[n][m] - pred[n][m]); dx = 2*fr0->x + fr0->x_half; dy = 2*fr0->y + fr0->y_half; dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 ); dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 ); DoPredChrom_P(x, y, dx, dy, curr_image, prev_image, pred_error); } else if (fr0->Mode == MODE_INTER4V) { for (n = 0; n < MB_SIZE; n++) for (m = 0; m < MB_SIZE; m++) pred_error->lum[n][m] = (int)(curr[n][m] - pred[n][m]); sum = 2*fr1->x + fr1->x_half + 2*fr2->x + fr2->x_half + 2*fr3->x + fr3->x_half + 2*fr4->x + fr4->x_half ; dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2); sum = 2*fr1->y + fr1->y_half + 2*fr2->y + fr2->y_half + 2*fr3->y + fr3->y_half + 2*fr4->y + fr4->y_half; dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2); DoPredChrom_P(x, y, dx, dy, curr_image, prev_image, pred_error); } else fprintf(stderr,"Illegal Mode in Predict_P (pred.c)\n"); return pred_error;}/**********************************************************************
*
* 函數(shù)名:B幀圖像的預(yù)測
* 函數(shù)功能:在PB模式下B幀編碼宏塊的運(yùn)動預(yù)測編碼
* 函數(shù)輸入:curr_image:當(dāng)前幀圖像
* prev_image:上一幀圖像
* prev_ipol:上一幀內(nèi)插圖像
* x:宏塊的位置(水平方位)
* y:宏塊的位置(豎直方位)
* MV:運(yùn)動向量
* recon_P:上一幀重構(gòu)的P幀編碼宏塊
* TRD:重構(gòu)宏塊的位置(水平方位)
* TRB:重構(gòu)宏塊的位置(豎直方位)
* 函數(shù)返回值:運(yùn)動估計后編碼宏塊差分?jǐn)?shù)據(jù)的指針
***********************************************************************/MB_Structure *Predict_B(PictImage *curr_image, PictImage *prev_image, unsigned char *prev_ipol,int x, int y, MotionVector *MV[5][MBR+1][MBC+2], MB_Structure *recon_P, int TRD,int TRB){ int i,j,k; int dx, dy, sad, sad_min=INT_MAX, curr[16][16], bdx=0, bdy=0; MB_Structure *p_err = (MB_Structure *)malloc(sizeof(MB_Structure)); MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure)); MotionVector *f[5]; int xvec, yvec, mvx, mvy; for (k = 0; k <= 4; k++) f[k] = MV[k][y/MB_SIZE+1][x/MB_SIZE+1]; /* 找到當(dāng)前幀的編碼宏塊 */ FindMB(x, y, curr_image->lum, curr); if (f[0]->Mode == MODE_INTER4V) { /* INTER4V模式 */ /* 計算前向預(yù)測 */ /* 亮度分量 */ for (j = -DEF_PBDELTA_WIN; j <= DEF_PBDELTA_WIN; j++) { for (i = -DEF_PBDELTA_WIN; i <= DEF_PBDELTA_WIN; i++) { FindForwLumPredPB(prev_ipol, x, y, f[1], &pred->lum[0][0], TRD, TRB, i, j, 8, 0); FindForwLumPredPB(prev_ipol, x, y, f[2], &pred->lum[0][8], TRD, TRB, i, j, 8, 1); FindForwLumPredPB(prev_ipol, x, y, f[3], &pred->lum[8][0], TRD, TRB, i, j, 8, 2); FindForwLumPredPB(prev_ipol, x, y, f[4], &pred->lum[8][8], TRD, TRB, i, j, 8, 3); sad = SAD_MB_integer(&curr[0][0],&pred->lum[0][0], 16,INT_MAX); if (i == 0 && j == 0) sad -= PREF_PBDELTA_NULL_VEC; if (sad < sad_min) { sad_min = sad; bdx = i; bdy = j; } } } FindForwLumPredPB(prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0); FindForwLumPredPB(prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1); FindForwLumPredPB(prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2); FindForwLumPredPB(prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3); /* 色度分量的運(yùn)動向量 */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx; yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy; } /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindChromBlock_P(x, y, dx, dy, prev_image, pred); /* 計算雙向運(yùn)動估計 */ FindBiDirLumPredPB(&recon_P->lum[0][0], f[1], &pred->lum[0][0], TRD, TRB, bdx, bdy, 0, 0); FindBiDirLumPredPB(&recon_P->lum[0][8], f[2], &pred->lum[0][8], TRD, TRB, bdx, bdy, 1, 0); FindBiDirLumPredPB(&recon_P->lum[8][0], f[3], &pred->lum[8][0], TRD, TRB, bdx, bdy, 0, 1); FindBiDirLumPredPB(&recon_P->lum[8][8], f[4], &pred->lum[8][8], TRD, TRB, bdx, bdy, 1, 1); /* 色度分量的運(yùn)動向量 */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { mvx = 2*f[k]->x + f[k]->x_half; mvy = 2*f[k]->y + f[k]->y_half; xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx; yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy; } /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindBiDirChrPredPB(recon_P, dx, dy, pred); } else { /* 幀間和INTER_Q模式 */ /* 計算前向運(yùn)動估計 */ for (j = -DEF_PBDELTA_WIN; j <= DEF_PBDELTA_WIN; j++) { for (i = -DEF_PBDELTA_WIN; i <= DEF_PBDELTA_WIN; i++) { dx = i; dy = j; /* 宏塊邊緣PB幀的向量差置為0 */ if (!mv_outside_frame) { if (x == 0) dx = 0; if (x == pels - MB_SIZE) dx = 0; if (y == 0) dy = 0; if (y == lines - MB_SIZE) dy = 0; } if (f[0]->Mode == MODE_INTRA || f[0]->Mode == MODE_INTRA_Q) { dx = dy = 0; } if (f[0]->x == 0 && f[0]->y == 0 && f[0]->x_half == 0 && f[0]->y_half == 0) { dx = dy = 0; } FindForwLumPredPB(prev_ipol, x, y, f[0], &pred->lum[0][0], TRD, TRB, dx, dy, 16, 0); sad = SAD_MB_integer(&curr[0][0],&pred->lum[0][0], 16, INT_MAX); if (i == 0 && j == 0) sad -= PREF_PBDELTA_NULL_VEC; if (sad < sad_min) { sad_min = sad; bdx = dx; bdy = dy; } } } FindForwLumPredPB(prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB, bdx,bdy,16,0); xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx); yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy); /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindChromBlock_P(x, y, dx, dy, prev_image, pred); /* 計算雙向運(yùn)動估計 */ FindBiDirLumPredPB(&recon_P->lum[0][0], f[0], &pred->lum[0][0], TRD, TRB, bdx, bdy, 0, 0); FindBiDirLumPredPB(&recon_P->lum[0][8], f[0], &pred->lum[0][8], TRD, TRB, bdx, bdy, 1, 0); FindBiDirLumPredPB(&recon_P->lum[8][0], f[0], &pred->lum[8][0], TRD, TRB, bdx, bdy, 0, 1); FindBiDirLumPredPB(&recon_P->lum[8][8], f[0], &pred->lum[8][8], TRD, TRB, bdx, bdy, 1, 1); /* 色度運(yùn)動向量 */ mvx = 2*f[0]->x + f[0]->x_half; xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx; xvec *= 4; mvy = 2*f[0]->y + f[0]->y_half; yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy; yvec *= 4; /* 色度運(yùn)動向量 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindBiDirChrPredPB(recon_P, dx, dy, pred); } /* 存放delta值 */ MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x = bdx; /* 半像素精度 */ MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y = bdy; MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x_half = 0; MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y_half = 0; /* 完成最后的運(yùn)動估計 */ for (j = 0; j < MB_SIZE; j++) for (i = 0; i < MB_SIZE; i++) p_err->lum[j][i] = *(curr_image->lum+x+i + (y+j)*pels) - pred->lum[j][i]; y >>= 1; x >>= 1; for (j = 0; j < MB_SIZE>>1; j++) for (i = 0; i < MB_SIZE>>1; i++) { p_err->Cr[j][i] = *(curr_image->Cr+x+i + (y+j)*cpels) - pred->Cr[j][i]; p_err->Cb[j][i] = *(curr_image->Cb+x+i + (y+j)*cpels) - pred->Cb[j][i]; } free(pred); return p_err;}/**********************************************************************
*
* 函數(shù)名:MB_Recon_B
* 函數(shù)功能:在PB模式下重構(gòu)B幀編碼宏塊
* 函數(shù)輸入:curr_image:當(dāng)前幀圖像
* prev_image:上一幀圖像
* prev_ipol:上一幀內(nèi)插圖像
* x:宏塊的位置(水平方位)
* y:宏塊的位置(豎直方位)
* MV:運(yùn)動向量
* recon_P:上一幀重構(gòu)的編碼宏塊
* TRD:重構(gòu)宏塊的位置(水平方位)
* TRB:重構(gòu)宏塊的位置(豎直方位)
* 函數(shù)返回值:重構(gòu)編碼宏塊數(shù)據(jù)的指針
***********************************************************************/
MB_Structure *MB_Recon_B(PictImage *prev_image, MB_Structure *diff, unsigned char *prev_ipol,int x, int y, MotionVector *MV[5][MBR+1][MBC+2], MB_Structure *recon_P,int TRD, int TRB){ int i,j,k; int dx, dy, bdx, bdy, mvx, mvy, xvec, yvec; MB_Structure *recon_B = (MB_Structure *)malloc(sizeof(MB_Structure)); MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure)); MotionVector *f[5]; for (k = 0; k <= 4; k++) f[k] = MV[k][y/MB_SIZE+1][x/MB_SIZE+1]; bdx = MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x; bdy = MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y; if (f[0]->Mode == MODE_INTER4V) { /* INTER4V模式 */ /* 計算前向運(yùn)動估計 */ /* 亮度分量 */ FindForwLumPredPB(prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0); FindForwLumPredPB(prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1); FindForwLumPredPB(prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2); FindForwLumPredPB(prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3); /* 色度運(yùn)動向量 */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx; yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy; } /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindChromBlock_P(x, y, dx, dy, prev_image, pred); /* 計算雙向運(yùn)動估計 */ FindBiDirLumPredPB(&recon_P->lum[0][0], f[1], &pred->lum[0][0], TRD, TRB, bdx, bdy, 0, 0); FindBiDirLumPredPB(&recon_P->lum[0][8], f[2], &pred->lum[0][8], TRD, TRB, bdx, bdy, 1, 0); FindBiDirLumPredPB(&recon_P->lum[8][0], f[3], &pred->lum[8][0], TRD, TRB, bdx, bdy, 0, 1); FindBiDirLumPredPB(&recon_P->lum[8][8], f[4], &pred->lum[8][8], TRD, TRB, bdx, bdy, 1, 1); /* 色度分量的運(yùn)動向量 */ xvec = yvec = 0; for (k = 1; k <= 4; k++) { mvx = 2*f[k]->x + f[k]->x_half; mvy = 2*f[k]->y + f[k]->y_half; xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx; yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy; } /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindBiDirChrPredPB(recon_P, dx, dy, pred); } else { /* 幀間或INTER_Q模式 */ /* 計算前向運(yùn)動估計 */ FindForwLumPredPB(prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB, bdx,bdy,16,0); xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx); yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy); /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindChromBlock_P(x, y, dx, dy, prev_image, pred); /* 計算雙向運(yùn)動估計 */ FindBiDirLumPredPB(&recon_P->lum[0][0], f[0], &pred->lum[0][0], TRD, TRB, bdx, bdy, 0, 0); FindBiDirLumPredPB(&recon_P->lum[0][8], f[0], &pred->lum[0][8], TRD, TRB, bdx, bdy, 1, 0); FindBiDirLumPredPB(&recon_P->lum[8][0], f[0], &pred->lum[8][0], TRD, TRB, bdx, bdy, 0, 1); FindBiDirLumPredPB(&recon_P->lum[8][8], f[0], &pred->lum[8][8], TRD, TRB, bdx, bdy, 1, 1); /* 色度分量的運(yùn)動向量 */ mvx = 2*f[0]->x + f[0]->x_half; xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx; xvec *= 4; mvy = 2*f[0]->y + f[0]->y_half; yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy; yvec *= 4; /* /* 根據(jù)表7-17得到近似值 */ dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2); dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2); FindBiDirChrPredPB(recon_P, dx, dy, pred); } /* 重構(gòu)出P幀的編碼宏塊 */ for (j = 0; j < MB_SIZE; j++) for (i = 0; i < MB_SIZE; i++) recon_B->lum[j][i] = pred->lum[j][i] + diff->lum[j][i]; for (j = 0; j < MB_SIZE>>1; j++) for (i = 0; i < MB_SIZE>>1; i++) { recon_B->Cr[j][i] = pred->Cr[j][i] + diff->Cr[j][i]; recon_B->Cb[j][i] = pred->Cb[j][i] + diff->Cb[j][i]; } free(pred); return recon_B;}
/**********************************************************************
*
* 函數(shù)名:FindForwLumPredPB
* 函數(shù)功能:在PB模式下計算前向亮度分量的運(yùn)動估計
* 函數(shù)輸入:prev_ipol:上一幀內(nèi)插圖像
* x_cur:當(dāng)前幀宏塊的位置(水平方位)
* y_cur:當(dāng)前幀宏塊的位置(豎直方位)
* fr:運(yùn)動向量
* pred:預(yù)測宏塊的數(shù)據(jù)指針
* TRD:重構(gòu)宏塊的位置(水平方位)
* TRB:重構(gòu)宏塊的位置(豎直方位)
* 函數(shù)返回值:重構(gòu)編碼宏塊數(shù)據(jù)的指針,宏塊的位置以及MV數(shù)據(jù)
***********************************************************************/
void FindForwLumPredPB(unsigned char *prev_ipol, int x_curr, int y_curr, MotionVector *fr, int *pred, int TRD, int TRB, int bdx, int bdy, int bs, int comp){ int i,j; int xvec,yvec,lx; lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels); /* 亮度分量 */ xvec = (TRB)*(2*fr->x + fr->x_half)/TRD + bdx; yvec = (TRB)*(2*fr->y + fr->y_half)/TRD + bdy; 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;}/**********************************************************************
*
* 函數(shù)名:FindBiDirLumPredPB
* 函數(shù)功能:在PB模式下尋找雙向亮度信息的預(yù)測值
* 函數(shù)輸入:recon_P:重構(gòu)恢復(fù)出來的P幀編碼宏塊
* fr:宏塊的運(yùn)動向量
* pred:預(yù)測宏塊的數(shù)據(jù)指針
* TRD:重構(gòu)宏塊的位置(水平方位)
* TRB:重構(gòu)宏塊的位置(豎直方位)*
***********************************************************************/void FindBiDirLumPredPB(int *recon_P, MotionVector *fr, int *pred, int TRD, int TRB, int bdx, int bdy, int nh, int nv){ int xstart,xstop,ystart,ystop; int xvec,yvec, mvx, mvy; mvx = 2*fr->x + fr->x_half; mvy = 2*fr->y + fr->y_half; xvec = (bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx); yvec = (bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -