📄 image.c
字号:
}
rewind (p_in);
status = fseek (p_in, frame_no * frame_size, 0);
if (status != 0)
{
sprintf(errortext, "Error in seeking frame no: %d\n", frame_no);
error(errortext);
}
for (j=0; j < img->height; j++)
for (i=0; i < img->width; i++)
imgY_org[j][i]=fgetc(p_in);
for (uv=0; uv < 2; uv++)
for (j=0; j < img->height_cr ; j++)
for (i=0; i < img->width_cr; i++)
imgUV_org[uv][j][i]=fgetc(p_in);
}
/************************************************************************
*
* Name : write_reconstructed_image()
*
* Description: Writes reconstructed image(s) to file
* This can be done more elegant!
*
************************************************************************/
void write_reconstructed_image()
{
int i, j, k;
if (p_dec != NULL)
{
if(img->type != B_IMG)
{
// write reconstructed image (IPPP)
if(input->successive_Bframe==0)
{
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
fputc(min(imgY[i][j],255),p_dec);
for (k=0; k < 2; ++k)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
fputc(min(imgUV[k][i][j],255),p_dec);
}
// write reconstructed image (IBPBP) : only intra written
else if (img->number==0 && input->successive_Bframe!=0)
{
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
fputc(min(imgY[i][j],255),p_dec);
for (k=0; k < 2; ++k)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
fputc(min(imgUV[k][i][j],255),p_dec);
}
// next P picture. This is saved with recon B picture after B picture coding
if (img->number!=0 && input->successive_Bframe!=0)
{
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
nextP_imgY[i][j]=imgY[i][j];
for (k=0; k < 2; ++k)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
nextP_imgUV[k][i][j]=imgUV[k][i][j];
}
}
else
{
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
fputc(min(imgY[i][j],255),p_dec);
for (k=0; k < 2; ++k)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
fputc(min(imgUV[k][i][j],255),p_dec);
/* If this is last B frame also store P frame */
if(img->b_frame_to_code == input->successive_Bframe)
{
/* save P picture */
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
fputc(min(nextP_imgY[i][j],255),p_dec);
for (k=0; k < 2; ++k)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
fputc(min(nextP_imgUV[k][i][j],255),p_dec);
}
}
}
}
/************************************************************************
*
* Name : interpolate_frame(), interpolate_frame_2()
*
* Description: Choose interpolation method depending on MV-resolution
*
************************************************************************/
void interpolate_frame()
{ // write to mref[]
int rpic;
rpic = img->frame_cycle = img->number % img->buf_cycle;
// printf ("Interpolate_frame: using reference picture %d\n", rpic);
if(input->mv_res)
oneeighthpix(0);
else
UnifiedOneForthPix(imgY, imgUV[0], imgUV[1],
mref[rpic], mcef[rpic][0], mcef[rpic][1],
Refbuf11[rpic]);
}
void interpolate_frame_2() // write to mref_P
{
if(input->mv_res)
oneeighthpix(1);
else
UnifiedOneForthPix(imgY, imgUV[0], imgUV[1], mref_P, mcef_P[0], mcef_P[1], Refbuf11_P);
}
static void GenerateFullPelRepresentation (pel_t **Fourthpel, pel_t *Fullpel, int xsize, int ysize) {
int x, y;
for (y=0; y<ysize; y++)
for (x=0; x<xsize; x++)
PutPel_11 (Fullpel, y, x, FastPelY_14 (Fourthpel, y*4, x*4));
}
/************************************************************************
* Name : UnifiedOne_ForthPix()
*
* Input: srcy, srcu, srcv, out4y, out4u, out4v
* Description:
* Upsample 4 times, store them in out4x. Color is simply copied
*
* Side Effects
* Uses (writes) img4Y_tmp. This should be moved to a static variable
* in this module
*
************************************************************************/
void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
pel_t **out4Y, pel_t **outU, pel_t **outV,
pel_t *ref11) {
int is;
int i,j,i2,j2,j4;
int ie2,je2;
for (j=0; j < img->height; j++)
{
for (i=0; i < img->width; i++)
{
i2=i*2;
is=(ONE_FOURTH_TAP[0][0]*(imgY[j][i ]+imgY[j][min(img->width-1,i+1)])+
ONE_FOURTH_TAP[1][0]*(imgY[j][max(0,i-1)]+imgY[j][min(img->width-1,i+2)])+
ONE_FOURTH_TAP[2][0]*(imgY[j][max(0,i-2)]+imgY[j][min(img->width-1,i+3)]));
img4Y_tmp[2*j][i2 ]=imgY[j][i]*1024; /* 1/1 pix pos */
img4Y_tmp[2*j][i2+1]=is*32; /* 1/2 pix pos */
}
}
for (i=0; i < img->width*2; i++)
{
for (j=0; j < img->height; j++)
{
j2=j*2;
j4=j*4;
/* change for TML4, use 6 TAP vertical filter */
is=(ONE_FOURTH_TAP[0][0]*(img4Y_tmp[j2 ][i]+img4Y_tmp[min(2*img->height-2,j2+2)][i])+
ONE_FOURTH_TAP[1][0]*(img4Y_tmp[max(0,j2-2)][i]+img4Y_tmp[min(2*img->height-2,j2+4)][i])+
ONE_FOURTH_TAP[2][0]*(img4Y_tmp[max(0,j2-4)][i]+img4Y_tmp[min(2*img->height-2,j2+6)][i]))/32;
img4Y_tmp[j2+1][i]=is; /* 1/2 pix */
PutPel_14 (out4Y, j4, i*2, (pel_t) max(0,min(255,(int)((img4Y_tmp[j2][i]+512)/1024)))); /* 1/2 pix */
PutPel_14 (out4Y, j4+2, i*2,(pel_t) max(0,min(255,(int)((is+512)/1024)))); /* 1/2 pix */
}
}
/* 1/4 pix */
/* luma */
ie2=(img->width-1)*4;
je2=(img->height-1)*4;
for (j=0;j<je2+4;j+=2)
for (i=0;i<ie2+3;i+=2) {
PutPel_14 (out4Y, j, i+1, (pel_t) (max(0,min(255,(int)(img4Y_tmp[j/2][i/2]+img4Y_tmp[j/2][min(ie2/2+1,i/2+1)]+1024)/2048))));
}
for (i=0;i<ie2+4;i++)
{
for (j=0;j<je2+3;j+=2)
{
if( i%2 == 0 ) {
PutPel_14 (out4Y, j+1, i, (pel_t)(max(0,min(255,(int)(img4Y_tmp[j/2][i/2]+img4Y_tmp[min(je2/2+1,j/2+1)][i/2]+1024)/2048))));
}
else {
PutPel_14 (out4Y, j+1, i, (pel_t)(max(0,min(255,(int)(
img4Y_tmp[j/2 ][i/2 ] +
img4Y_tmp[min(je2/2+1,j/2+1)][i/2 ] +
img4Y_tmp[j/2 ][min(ie2/2+1,i/2+1)] +
img4Y_tmp[min(je2/2+1,j/2+1)][min(ie2/2+1,i/2+1)] + 2048)/4096))));
}
/* "funny posision" */
if( ((i&3) == 3)&&(((j+1)&3) == 3))
{
PutPel_14 (out4Y, j+1, i, (pel_t) ((
FastPelY_14 (out4Y, j-2, i-3) +
FastPelY_14 (out4Y, min(je2,j+2), i-3) +
FastPelY_14 (out4Y, j-2, min(ie2,i+1)) +
FastPelY_14 (out4Y, min(je2,j+2), min(ie2,i+1))
+ 2 )/4));
}
}
}
/* Chroma: */
for (j=0; j < img->height_cr; j++) {
memcpy(outU[j],imgUV[0][j],img->width_cr); // just copy 1/1 pix, interpolate "online"
memcpy(outV[j],imgUV[1][j],img->width_cr);
}
// Generate 1/1th pel representation (used for integer pel MV search)
GenerateFullPelRepresentation (out4Y, ref11, img->width, img->height);
}
/************************************************************************
*
* Name : oneeighthpix()
*
* Description: Upsample 4 times for 1/8-pel estimation and store in buffer
* for multiple reference frames. 1/8-pel resolution is calculated
* during the motion estimation on the fly with bilinear interpolation.
*
************************************************************************/
void oneeighthpix(int prior_B_frame)
{
static int h1[8] = { -3, 12, -37, 229, 71, -21, 6, -1 };
static int h2[8] = { -3, 12, -39, 158, 158, -39, 12, -3 };
static int h3[8] = { -1, 6, -21, 71, 229, -37, 12, -3 };
int scale=256;
int uv,x,y,x4,y4;
int nx_out, ny_out, nx_1, ny_1;
int i0,i1,i2,i3,i4;
byte *p;
img->frame_cycle=img->number % img->buf_cycle; /*GH input->no_multpred used insteadof MAX_MULT_PRED
frame buffer size = input->no_multpred+1*/
nx_out = 4*img->width;
ny_out = 4*img->height;
nx_1 = img->width-1;
ny_1 = img->height-1;
/*horizontal filtering filtering */
for(y=0;y<img->height;y++)
{
p = &imgY[y][0];
for(x=0;x<img->width;x++)
{
i0=*(p + x);
i1=(int)( h1[0]* *(p + max(0 ,x-3)) +
h1[1]* *(p + max(0 ,x-2)) +
h1[2]* *(p + max(0 ,x-1)) +
h1[3]* *(p + x ) +
h1[4]* *(p + min(nx_1,x+1)) +
h1[5]* *(p + min(nx_1,x+2)) +
h1[6]* *(p + min(nx_1,x+3)) +
h1[7]* *(p + min(nx_1,x+4)) + scale/2.0 ) / scale;
i2=(int)( h2[0]* *(p + max(0 ,x-3)) +
h2[1]* *(p + max(0 ,x-2)) +
h2[2]* *(p + max(0 ,x-1)) +
h2[3]* *(p + x ) +
h2[4]* *(p + min(nx_1,x+1)) +
h2[5]* *(p + min(nx_1,x+2)) +
h2[6]* *(p + min(nx_1,x+3)) +
h2[7]* *(p + min(nx_1,x+4)) + scale/2.0 ) / scale;
i3=(int)( h3[0]* *(p + max(0 ,x-3)) +
h3[1]* *(p + max(0 ,x-2)) +
h3[2]* *(p + max(0 ,x-1)) +
h3[3]* *(p + x ) +
h3[4]* *(p + min(nx_1,x+1)) +
h3[5]* *(p + min(nx_1,x+2)) +
h3[6]* *(p + min(nx_1,x+3)) +
h3[7]* *(p + min(nx_1,x+4)) + scale/2.0 ) / scale;
i4=*(p + min(nx_1,x+1));
x4=4*x;
img8Y_tmp[x4 ][y] = i0;
img8Y_tmp[x4+1][y] = max(0,min(255,i1));
img8Y_tmp[x4+2][y] = max(0,min(255,i2));
img8Y_tmp[x4+3][y] = max(0,min(255,i3));
}
}
for(x4=0;x4<nx_out;x4++)
{
p=&img8Y_tmp[x4][0];
for(y=0;y<img->height;y++)
{
i0=*(p + y);
i1=(int)( h1[0]* *(p + max(0 ,y-3)) +
h1[1]* *(p + max(0 ,y-2)) +
h1[2]* *(p + max(0 ,y-1)) +
h1[3]* *(p + ( y )) +
h1[4]* *(p + min(ny_1,y+1)) +
h1[5]* *(p + min(ny_1,y+2)) +
h1[6]* *(p + min(ny_1,y+3)) +
h1[7]* *(p + min(ny_1,y+4)) + scale/2.0 ) / scale;
i2=(int)( h2[0]* *(p + max(0 ,y-3)) +
h2[1]* *(p + max(0 ,y-2)) +
h2[2]* *(p + max(0 ,y-1)) +
h2[3]* *(p + ( y )) +
h2[4]* *(p + min(ny_1,y+1)) +
h2[5]* *(p + min(ny_1,y+2)) +
h2[6]* *(p + min(ny_1,y+3)) +
h2[7]* *(p + min(ny_1,y+4)) + scale/2.0 ) / scale;
i3=(int)( h3[0]* *(p + max(0 ,y-3)) +
h3[1]* *(p + max(0 ,y-2)) +
h3[2]* *(p + max(0 ,y-1)) +
h3[3]* *(p + ( y )) +
h3[4]* *(p + min(ny_1,y+1)) +
h3[5]* *(p + min(ny_1,y+2)) +
h3[6]* *(p + min(ny_1,y+3)) +
h3[7]* *(p + min(ny_1,y+4)) + scale/2.0 ) / scale;
i4=*(p + min(ny_1,y+1));
y4=4*y;
if(prior_B_frame)
{
PutPel_14 (mref_P, y4, x4, (pel_t) i0);
PutPel_14 (mref_P, y4+1, x4, (pel_t) max(0,min(255,i1)));
PutPel_14 (mref_P, y4+2, x4, (pel_t) max(0,min(255,i2)));
PutPel_14 (mref_P, y4+3, x4, (pel_t) max(0,min(255,i3)));
}
else
{
PutPel_11 (Refbuf11[img->frame_cycle], y4/4, x4/4, (pel_t) i0);
PutPel_14 (mref[img->frame_cycle], y4, x4, (pel_t) i0);
PutPel_14 (mref[img->frame_cycle], y4+1, x4, (pel_t) max(0,min(255,i1)));
PutPel_14 (mref[img->frame_cycle], y4+2, x4, (pel_t) max(0,min(255,i2)));
PutPel_14 (mref[img->frame_cycle], y4+3, x4, (pel_t) max(0,min(255,i3)));
}
}
}
// Chroma and full pel representation:
if(prior_B_frame)
{
for (uv=0; uv < 2; uv++)
for (y=0; y < img->height_cr; y++)
memcpy(mcef_P[uv][y],imgUV[uv][y],img->width_cr); /* just copy 1/1 pix, interpolate "online" */
GenerateFullPelRepresentation (mref_P, Refbuf11_P, img->width, img->height);
}
else
{
for (uv=0; uv < 2; uv++)
for (y=0; y < img->height_cr; y++)
memcpy(mcef[img->frame_cycle][uv][y],imgUV[uv][y],img->width_cr); /* just copy 1/1 pix, interpolate "online" */
GenerateFullPelRepresentation (mref[img->frame_cycle], Refbuf11[img->frame_cycle], img->width, img->height);
}
// Generate 1/1th pel representation (used for integer pel MV search)
}
/************************************************************************
*
* Name : find_snr()
*
* Description: Find SNR for all three components
*
************************************************************************/
void find_snr()
{
int i,j;
int diff_y,diff_u,diff_v;
int impix;
/* Calculate PSNR for Y, U and V. */
/* Luma. */
impix = img->height*img->width;
diff_y=0;
for (i=0; i < img->width; ++i)
{
for (j=0; j < img->height; ++j)
{
diff_y += img->quad[abs(imgY_org[j][i]-imgY[j][i])];
}
}
/* Chroma. */
diff_u=0;
diff_v=0;
for (i=0; i < img->width_cr; i++)
{
for (j=0; j < img->height_cr; j++)
{
diff_u += img->quad[abs(imgUV_org[0][j][i]-imgUV[0][j][i])];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -