📄 coder.c
字号:
* Returns:
* Side effects:
*
***********************************************************************/
void ReconImage (int i, int j, MB_Structure *data, PictImage *recon)
{
int n;
register int m;
int x_curr, y_curr;
x_curr = i * MB_SIZE;
y_curr = j * MB_SIZE;
/* Fill in luminance data */
for (n = 0; n < MB_SIZE; n++)
for (m= 0; m < MB_SIZE; m++) {
*(recon->lum + x_curr+m + (y_curr+n)*pels) = data->lum[n][m];
}
/* Fill in chrominance data */
for (n = 0; n < MB_SIZE>>1; n++)
for (m = 0; m < MB_SIZE>>1; m++) {
*(recon->Cr + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cr[n][m];
*(recon->Cb + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cb[n][m];
}
return;
}
/**********************************************************************
*
* Name: InterpolateImage
* Description: Interpolates a complete image for easier half
* pel prediction
*
* Input: pointer to image structure
* Returns: pointer to interpolated image
* Side effects: allocates memory to interpolated image
*
***********************************************************************/
unsigned char *InterpolateImage(unsigned char *image, int width, int height)
{
unsigned char *ipol_image, *ii, *oo;
int i,j;
ipol_image = (unsigned char *)malloc(sizeof(char)*width*height*4);
ii = ipol_image;
oo = image;
/* main image */
for (j = 0; j < height-1; j++) {
for (i = 0; i < width-1; i++) {
*(ii + (i<<1)) = *(oo + i);
*(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
*(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1)>>1;
*(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) +
*(oo+i+width) + *(oo+i+1+width) + 2)>>2;
}
/* last pels on each line */
*(ii+ (width<<1) - 2) = *(oo + width - 1);
*(ii+ (width<<1) - 1) = *(oo + width - 1);
*(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
*(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
ii += (width<<2);
oo += width;
}
/* last lines */
for (i = 0; i < width-1; i++) {
*(ii+ (i<<1)) = *(oo + i);
*(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
*(ii+ (width<<1)+ (i<<1)) = *(oo + i);
*(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
}
/* bottom right corner pels */
*(ii + (width<<1) - 2) = *(oo + width -1);
*(ii + (width<<1) - 1) = *(oo + width -1);
*(ii + (width<<2) - 2) = *(oo + width -1);
*(ii + (width<<2) - 1) = *(oo + width -1);
return ipol_image;
}
/**********************************************************************
*
* Name: MotionEstimatePicture
* Description: Finds integer and half pel motion estimation
* and chooses 8x8 or 16x16
*
* Input: current image, previous image, interpolated
* reconstructed previous image, seek_dist,
* motion vector array
* Returns:
* Side effects: allocates memory for MV structure
*
***********************************************************************/
void MotionEstimatePicture(unsigned char *curr, unsigned char *prev,
unsigned char *prev_ipol, int seek_dist,
MotionVector *MV[6][MBR+1][MBC+2], int gobsync)
{
int i,j,k;
int pmv0,pmv1,xoff,yoff;
int curr_mb[16][16];
int sad8 = INT_MAX, sad16, sad0;
int newgob;
MotionVector *f0,*f1,*f2,*f3,*f4;
/* Do motion estimation and store result in array */
for ( j = 0; j < lines/MB_SIZE; j++) {
newgob = 0;
if (gobsync && j%gobsync == 0) {
newgob = 1;
}
for ( i = 0; i < pels/MB_SIZE; i++) {
for (k = 0; k < 6; k++)
MV[k][j+1][i+1] = (MotionVector *)malloc(sizeof(MotionVector));
/* Integer pel search */
f0 = MV[0][j+1][i+1];
f1 = MV[1][j+1][i+1];
f2 = MV[2][j+1][i+1];
f3 = MV[3][j+1][i+1];
f4 = MV[4][j+1][i+1];
/* Here the PMV's are found using integer motion vectors */
/* (NB should add explanation for this )*/
FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0);
if (long_vectors) {
xoff = pmv0/2; /* always divisable by two */
yoff = pmv1/2;
}
else {
xoff = yoff = 0;
}
MotionEstimation(curr, prev, i*MB_SIZE, j*MB_SIZE,
xoff, yoff, seek_dist, MV, &sad0);
sad16 = f0->min_error;
if (advanced)
sad8 = f1->min_error + f2->min_error + f3->min_error + f4->min_error;
f0->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE, mmin(sad8,sad16));
/* Half pel search */
if (f0->Mode != MODE_INTRA) {
FindMB(i*MB_SIZE,j*MB_SIZE ,curr, curr_mb);
FindHalfPel(i*MB_SIZE,j*MB_SIZE,f0, prev_ipol, &curr_mb[0][0],16,0);
sad16 = f0->min_error;
if (advanced) {
FindHalfPel(i*MB_SIZE,j*MB_SIZE,f1, prev_ipol, &curr_mb[0][0],8,0);
FindHalfPel(i*MB_SIZE,j*MB_SIZE,f2, prev_ipol, &curr_mb[0][8],8,1);
FindHalfPel(i*MB_SIZE,j*MB_SIZE,f3, prev_ipol, &curr_mb[8][0],8,2);
FindHalfPel(i*MB_SIZE,j*MB_SIZE,f4, prev_ipol, &curr_mb[8][8],8,3);
sad8 = f1->min_error +f2->min_error +f3->min_error +f4->min_error;
sad8 += PREF_16_VEC;
/* Choose Zero Vector, 8x8 or 16x16 vectors */
if (sad0 < sad8 && sad0 < sad16) {
f0->x = f0->y = 0;
f0->x_half = f0->y_half = 0;
}
else {
if (sad8 < sad16)
f0->Mode = MODE_INTER4V;
}
}
else {
/* Choose Zero Vector or 16x16 vectors */
if (sad0 < sad16) {
f0->x = f0->y = 0;
f0->x_half = f0->y_half = 0;
}
}
}
else
for (k = 0; k < 5; k++)
ZeroVec(MV[k][j+1][i+1]);
}
}
#ifdef PRINTMV
fprintf(stdout,"Motion estimation\n");
fprintf(stdout,"16x16 vectors:\n");
for ( j = 0; j < lines/MB_SIZE; j++) {
for ( i = 0; i < pels/MB_SIZE; i++) {
if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
fprintf(stdout," %3d%3d",
2*MV[0][j+1][i+1]->x + MV[0][j+1][i+1]->x_half,
2*MV[0][j+1][i+1]->y + MV[0][j+1][i+1]->y_half);
else
fprintf(stdout," . . ");
}
fprintf(stdout,"\n");
}
if (advanced) {
fprintf(stdout,"8x8 vectors:\n");
for (k = 1; k < 5; k++) {
fprintf(stdout,"Block: %d\n", k-1);
for ( j = 0; j < lines/MB_SIZE; j++) {
for ( i = 0; i < pels/MB_SIZE; i++) {
if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
fprintf(stdout," %3d%3d",
2*MV[k][j+1][i+1]->x + MV[k][j+1][i+1]->x_half,
2*MV[k][j+1][i+1]->y + MV[k][j+1][i+1]->y_half);
else
fprintf(stdout," . . ");
}
fprintf(stdout,"\n");
}
}
}
#endif
return;
}
/**********************************************************************
*
* Name: MakeEdgeImage
* Description: Copies edge pels for use with unrestricted
* motion vector mode
*
* Input: pointer to source image, destination image
* width, height, edge
* Returns:
* Side effects:
*
***********************************************************************/
void MakeEdgeImage(unsigned char *src, unsigned char *dst, int width,
int height, int edge)
{
int i,j;
unsigned char *p1,*p2,*p3,*p4;
unsigned char *o1,*o2,*o3,*o4;
/* center image */
p1 = dst;
o1 = src;
for (j = 0; j < height;j++) {
memcpy(p1,o1,width);
p1 += width + (edge<<1);
o1 += width;
}
/* left and right edges */
p1 = dst-1;
o1 = src;
for (j = 0; j < height;j++) {
for (i = 0; i < edge; i++) {
*(p1 - i) = *o1;
*(p1 + width + i + 1) = *(o1 + width - 1);
}
p1 += width + (edge<<1);
o1 += width;
}
/* top and bottom edges */
p1 = dst;
p2 = dst + (width + (edge<<1))*(height-1);
o1 = src;
o2 = src + width*(height-1);
for (j = 0; j < edge;j++) {
p1 = p1 - (width + (edge<<1));
p2 = p2 + (width + (edge<<1));
for (i = 0; i < width; i++) {
*(p1 + i) = *(o1 + i);
*(p2 + i) = *(o2 + i);
}
}
/* corners */
p1 = dst - (width+(edge<<1)) - 1;
p2 = p1 + width + 1;
p3 = dst + (width+(edge<<1))*(height)-1;
p4 = p3 + width + 1;
o1 = src;
o2 = o1 + width - 1;
o3 = src + width*(height-1);
o4 = o3 + width - 1;
for (j = 0; j < edge; j++) {
for (i = 0; i < edge; i++) {
*(p1 - i) = *o1;
*(p2 + i) = *o2;
*(p3 - i) = *o3;
*(p4 + i) = *o4;
}
p1 = p1 - (width + (edge<<1));
p2 = p2 - (width + (edge<<1));
p3 = p3 + width + (edge<<1);
p4 = p4 + width + (edge<<1);
}
}
/**********************************************************************
*
* Name: Clip
* Description: clips recontructed data 0-255
*
* Input: pointer to recon. data structure
* Side effects: data structure clipped
*
***********************************************************************/
void Clip(MB_Structure *data)
{
int m,n;
for (n = 0; n < 16; n++) {
for (m = 0; m < 16; m++) {
data->lum[n][m] = mmin(255,mmax(0,data->lum[n][m]));
}
}
for (n = 0; n < 8; n++) {
for (m = 0; m < 8; m++) {
data->Cr[n][m] = mmin(255,mmax(0,data->Cr[n][m]));
data->Cb[n][m] = mmin(255,mmax(0,data->Cb[n][m]));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -