?? pred.c
字號(hào):
/************************************************* * libr263: fast H.263 encoder library * * Copyright (C) 1996, Roalt Aalmoes, Twente University * SPA multimedia group * * Based on Telenor TMN 1.6 encoder (Copyright (C) 1995, Telenor R&D) * created by Karl Lillevold * * Author encoder: Roalt Aalmoes, <aalmoes@huygens.nl> * * Date: 31-07-96 **************************************************/#include "sim.h"
// 插入圖像和當(dāng)前圖像x,y處宏塊的差值(宏塊結(jié)構(gòu))
//curr_image當(dāng)前宏塊,prev_image重建圖像,prev_ipol插入圖像,x,y當(dāng)前宏塊象素位置,MV_ptr圖像mv值MB_Structure *Predict_P(unsigned int *curr_image, unsigned int *prev_image, unsigned int *prev_ipol, int x, int y, MotionVector *MV_ptr){ int m,n; int curr[16][16]; int pred[16][16]; MotionVector *fr0; int dx, dy; int xmb, ymb; MB_Structure *pred_error; pred_error = (MB_Structure *)malloc(sizeof(MB_Structure)); xmb = x/MB_SIZE; ymb = y/MB_SIZE; fr0 = MV_ptr + ymb*mbc + xmb;// mv矢量 /* Find MB in current image */
//從(x,y)處,開(kāi)始,得到當(dāng)前數(shù)據(jù)宏塊curr[16][16] FindMB(x, y, curr_image, curr);
/* Find prediction based on half pel MV */
// 從插入圖像prev_ipol的相對(duì)位置,取出對(duì)應(yīng)的原始宏塊值,放入pred[16][16]中 FindPred(x, y, fr0, prev_ipol, &pred[0][0]); /* Do the actual prediction */ if (fr0->Mode == MODE_INTER)
{
//預(yù)測(cè)差值 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 fprintf(stderr,"Illegal Mode in Predict_P (pred.c)\n"); return pred_error;}
//預(yù)測(cè)色度塊 ?????????void DoPredChrom_P(int x_curr, int y_curr, int dx, int dy, unsigned int *curr, unsigned int *prev, MB_Structure *pred_error){ int m,n; int x, y, ofx, ofy, pel, lx; int xint, yint; int xh, yh; lx = pels/2; x = x_curr>>1; y = y_curr>>1; xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; if (!xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n;
/* prev+vskip does not work directly... */ pel=*(prev+vskip + ofx + (ofy )*lx); pred_error->Cr[n][m] = (int)(*(curr+vskip + x+m + (y+n)*cpels) - pel); pel=*(prev+uskip + ofx + (ofy )*lx); pred_error->Cb[n][m] = (int)(*(curr + uskip + x+m + (y+n)*cpels) - pel); } } } else if (!xh && yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip + ofx + (ofy )*lx)+ *(prev+vskip + ofx + (ofy+yh)*lx) + 1)>>1; pred_error->Cr[n][m] = (int)(*(curr+vskip + x+m + (y+n)*cpels) - pel); pel=(*(prev+uskip + ofx + (ofy )*lx)+ *(prev+uskip + ofx + (ofy+yh)*lx) + 1)>>1; pred_error->Cb[n][m] = (int)(*( curr+uskip + x+m + (y+n)*cpels) - pel); } } } else if (xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx) + 1)>>1; pred_error->Cr[n][m] = (int)(*(curr+vskip + x+m + (y+n)*cpels) - pel); pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx) + 1)>>1; pred_error->Cb[n][m] = (int)( *( curr+uskip + x+m + (y+n)*cpels) - pel); } } } else { /* xh && yh */ for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx)+ *(prev+vskip+ofx + (ofy+yh)*lx)+ *(prev+vskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; pred_error->Cr[n][m] = (int)(*(curr+vskip + x+m + (y+n)*cpels) - pel); pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx)+ *(prev+uskip+ofx + (ofy+yh)*lx)+ *(prev+uskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; pred_error->Cb[n][m] = (int)(*(curr+uskip + x+m + (y+n)*cpels) - pel); } } } return;}
// 找到運(yùn)動(dòng)矢量對(duì)應(yīng)的插入圖像中的宏塊的值,xy宏塊位置,fr為矢量,prev插入圖像,放入pred[16][16]中void FindPred(int x, int y, MotionVector *fr, unsigned int *prev, int *pred){ int n; int new_x, new_y; int *prev_ptr;
// 新的位置 new_x = 2*(x + fr->x) + fr->x_half; new_y = 2*(y + fr->y) + fr->y_half; prev_ptr = (int *) prev + 2*new_y*pels + new_x; /* Fill pred. data */ for (n = 0; n < 16; n++) { /* Interpolated data -> too bad it can't be done in longs... */ *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += 2; *(pred++) = *(prev_ptr); prev_ptr += pels*4 - 30; } return;}//p幀中重建宏塊MB_Structure *MB_Recon_P(unsigned int *prev_image, unsigned int *prev_ipol, MB_Structure *diff, int x_curr, int y_curr, MotionVector *MV_ptr){ MB_Structure *recon_data = (MB_Structure *)malloc(sizeof(MB_Structure)); MotionVector *fr0; int dx, dy; fr0 = MV_ptr + (y_curr/MB_SIZE)*mbc + (x_curr/MB_SIZE); if (fr0->Mode == MODE_INTER) { /* Inter 16x16 */ ReconLumBlock_P(x_curr,y_curr,fr0,prev_ipol,&diff->lum[0][0]); 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 ); ReconChromBlock_P(x_curr, y_curr, dx, dy, prev_image, diff); } memcpy(recon_data, diff, sizeof(MB_Structure)); return recon_data;}
void ReconLumBlock_P(int x, int y, MotionVector *fr, unsigned int *prev, int *data){ int m, n; int x1, y1; int *data_ptr = data; unsigned int *prev_ptr; x1 = 2*(x + fr->x) + fr->x_half; y1 = 2*(y + fr->y) + fr->y_half; prev_ptr = prev + x1 + y1*2*pels; for (n = 0; n < 16; n++) { for (m = 0; m < 16; m++) { *data_ptr++ += (int)(*prev_ptr); prev_ptr += 2; } prev_ptr += 2*2*pels - 32; } return;}void ReconChromBlock_P(int x_curr, int y_curr, int dx, int dy, unsigned int *prev, MB_Structure *data){ int m,n; int x, y, ofx, ofy, pel,lx; int xint, yint; int xh, yh; lx = pels/2; x = x_curr>>1; y = y_curr>>1; xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; if (!xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=*(prev+vskip+ ofx + (ofy )*lx); data->Cr[n][m] += pel; pel=*(prev+uskip + ofx + (ofy )*lx); data->Cb[n][m] += pel; } } } else if (!xh && yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ ofx + (ofy )*lx)+ *(prev+vskip+ ofx + (ofy+yh)*lx) + 1)>>1; data->Cr[n][m] += pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx + (ofy+yh)*lx) + 1)>>1; data->Cb[n][m] += pel; } } } else if (xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx) + 1)>>1; data->Cr[n][m] += pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx) + 1)>>1; data->Cb[n][m] += pel; } } } else { /* xh && yh */ for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx)+ *(prev+vskip+ofx + (ofy+yh)*lx)+ *(prev+vskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; data->Cr[n][m] += pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx)+ *(prev+uskip+ofx + (ofy+yh)*lx)+ *(prev+uskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; data->Cb[n][m] += pel; } } } return;}void FindChromBlock_P(int x_curr, int y_curr, int dx, int dy, unsigned int *prev, MB_Structure *data){ int m,n; int x, y, ofx, ofy, pel,lx; int xint, yint; int xh, yh; lx = pels/2; x = x_curr>>1; y = y_curr>>1; xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; if (!xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=*(prev+vskip+ofx + (ofy )*lx); data->Cr[n][m] = pel; pel=*(prev+uskip+ofx + (ofy )*lx); data->Cb[n][m] = pel; } } } else if (!xh && yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx + (ofy+yh)*lx) + 1)>>1; data->Cr[n][m] = pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx + (ofy+yh)*lx) + 1)>>1; data->Cb[n][m] = pel; } } } else if (xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx) + 1)>>1; data->Cr[n][m] = pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx) + 1)>>1; data->Cb[n][m] = pel; } } } else { /* xh && yh */ for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; pel=(*(prev+vskip+ofx + (ofy )*lx)+ *(prev+vskip+ofx+xh + (ofy )*lx)+ *(prev+vskip+ofx + (ofy+yh)*lx)+ *(prev+vskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; data->Cr[n][m] = pel; pel=(*(prev+uskip+ofx + (ofy )*lx)+ *(prev+uskip+ofx+xh + (ofy )*lx)+ *(prev+uskip+ofx + (ofy+yh)*lx)+ *(prev+uskip+ofx+xh + (ofy+yh)*lx)+ 2)>>2; data->Cb[n][m] = pel; } } } return;}//curr當(dāng)前圖像,x,y位置的宏塊, min_SAD當(dāng)前mv的誤差差值
//此宏塊的整體方差較小時(shí),A小于(inter誤差 - 500)時(shí),用interint ChooseMode(unsigned int *curr, int x_pos, int y_pos, int min_SAD){ int i,j; int MB_mean = 0, A = 0; int y_off; for (j = 0; j < MB_SIZE; j++)
{ y_off = (y_pos + j) * pels; for (i = 0; i < MB_SIZE; i++)
{ MB_mean += *(curr + x_pos + i + y_off); } }
MB_mean /= (MB_SIZE*MB_SIZE); for (j = 0; j < MB_SIZE; j++)
{ y_off = (y_pos + j) * pels; for (i = 0; i < MB_SIZE; i++)
{ A += abs( *(curr + x_pos + i + y_off) - MB_mean ); } }
//16*16的方差較小時(shí),用intra if (A < (min_SAD - 500)) return MODE_INTRA; else return MODE_INTER;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -