📄 image.c
字号:
frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
*/
FrameNum++; //HiSilicon
fclose(file);
}
/*
*************************************************************************
* Function:Find PSNR for all three components.Compare decoded frame with
the original sequence. Read inp->jumpd frames to reflect frame skipping.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void find_snr(
struct snr_par *snr, //!< pointer to snr parameters
struct img_par *img, //!< pointer to image parameters
FILE *p_ref) //!< filestream to reference YUV file
{
int i,j;
int diff_y,diff_u,diff_v;
int uv;
int status;
snr->snr_y=0.0;
snr->snr_u=0.0;
snr->snr_v=0.0;
/* HiSilicon, 2007.03.21
if(img->type==I_IMG ) // I, P pictures
{
frame_no=img->tr;
}else if(img->type==P_IMG)
{
frame_no=img->tr;
}else// B pictures
{
diff=nextP_tr-img->tr;
frame_no=(img->number-1)*P_interval-diff;
}
*/
rewind(p_ref);
status = fseek (p_ref, FrameNum*img->height*img->width*3/2, 0);
if (status != 0)
{
snprintf(errortext, ET_SIZE, "Error in seeking img->tr: %d", img->tr);
error(errortext, 500);
}
for (j=0; j < img->height; j++)
for (i=0; i < img->width; i++)
{
imgY_ref[j][i]=fgetc(p_ref);
}
for (uv=0; uv < 2; uv++)
for (j=0; j < img->height_cr ; j++)
for (i=0; i < img->width_cr; i++)
imgUV_ref[uv][j][i]=fgetc(p_ref);
img->quad[0]=0;
diff_y=0;
for (j=0; j < img->height; ++j)
{
for (i=0; i < img->width; ++i)
{
if(img->type==B_IMG && !eos) //HiSilicon
diff_y += img->quad[abs(imgY[j][i]-imgY_ref[j][i])];
else
diff_y += img->quad[abs(imgY_prev[j][i]-imgY_ref[j][i])];
if(img->type==B_IMG && !eos)
if(imgY[j][i]!=imgY_ref[j][i])
{
int mb_nr;
mb_nr = (j/16)*(img->width/16)+i/16;
}
else
if(imgY[j][i]!=imgY_prev[j][i])
{
int mb_nr;
mb_nr = (j/16)*(img->width/16)+i/16;
}
}
}
// Chroma
diff_u=0;
diff_v=0;
//4:0:0 WANGJP START
if (chroma_format)
{
for (j=0; j < img->height_cr; ++j)
{
for (i=0; i < img->width_cr; ++i)
{
if(img->type==B_IMG && !eos)
{
diff_u += img->quad[abs(imgUV_ref[0][j][i]-imgUV[0][j][i])];
diff_v += img->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])];
}
else
{
diff_u += img->quad[abs(imgUV_ref[0][j][i]-imgUV_prev[0][j][i])];
diff_v += img->quad[abs(imgUV_ref[1][j][i]-imgUV_prev[1][j][i])];
}
if(img->type==B_IMG && !eos)
if(imgUV_ref[0][j][i]!=imgUV[0][j][i])
{
int mb_nr;
mb_nr = (j/16)*(img->width/16)+i/8;
}
else
if(imgUV_prev[0][j][i]!=imgUV[0][j][i])
{
int mb_nr;
mb_nr = (j/16)*(img->width/16)+i/8;
}
}
}
}//WANGJP END
// Collecting SNR statistics
if (diff_y != 0)
snr->snr_y=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)diff_y)); // luma snr for current frame
if (diff_u != 0)
snr->snr_u=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_u))); // chroma snr for current frame
if (diff_v != 0)
snr->snr_v=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_v))); // chroma snr for current frame
if (img->number == 0) // first
{
snr->snr_y1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)diff_y)); // keep luma snr for first frame
snr->snr_u1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_u))); // keep chroma snr for first frame
snr->snr_v1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_v))); // keep chroma snr for first frame
snr->snr_ya=snr->snr_y1;
snr->snr_ua=snr->snr_u1;
snr->snr_va=snr->snr_v1;
if (diff_y == 0)
snr->snr_ya=50; // need to assign a reasonable large number so avg snr of entire sequece isn't infinite
if (diff_u == 0)
snr->snr_ua=50;
if (diff_v == 0)
snr->snr_va=50;
}
else
{
snr->snr_ya=(float)(snr->snr_ya*(img->number+Bframe_ctr)+snr->snr_y)/(img->number+Bframe_ctr+1); // average snr chroma for all frames
snr->snr_ua=(float)(snr->snr_ua*(img->number+Bframe_ctr)+snr->snr_u)/(img->number+Bframe_ctr+1); // average snr luma for all frames
snr->snr_va=(float)(snr->snr_va*(img->number+Bframe_ctr)+snr->snr_v)/(img->number+Bframe_ctr+1); // average snr luma for all frames
}
}
/*
*************************************************************************
* Function:Interpolation of 1/4 subpixel
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void get_block(int ref_frame,int x_pos, int y_pos, struct img_par *img, int block[8][8], unsigned char **ref_pic)
{
int dx, dy;
int x, y;
int i, j;
int maxold_x,maxold_y;
int result;
int tmp_res[26][26];
int tmp_res_2[26][26];
static const int COEF_HALF[4] = {
-1, 5, 5, -1
};
static const int COEF_QUART[4] = {
1, 7, 7, 1
};
// A a 1 b B
// c d e f
// 2 h 3 i
// j k l m
// C D
dx = x_pos&3;
dy = y_pos&3;
x_pos = (x_pos-dx)/4;
y_pos = (y_pos-dy)/4;
maxold_x = img->width-1;
maxold_y = img->height-1;
if (dx == 0 && dy == 0) { //fullpel position: A
for (j = 0; j < B8_SIZE; j++)
for (i = 0; i < B8_SIZE; i++)
block[i][j] = ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i))];
}
else
{ /* other positions */
if((dx==2) && (dy==0)){//horizonal 1/2 position: 1
for (j = 0; j < B8_SIZE; j++){
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
result += ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF_HALF[x+1];
block[i][j] = max(0, min(255, (result+4)/8));
}
}
}
else if(((dx==1) || (dx==3)) && (dy==0)){//horizonal 1/4 position: a and b
for (j = 0; j < B8_SIZE; j++) {
for (i = -1; i < B8_SIZE+1; i++) {
for (result = 0, x = -1; x < 3; x++)
result += ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF_HALF[x+1];
tmp_res[j][2*(i+1)] = result;
tmp_res[j][2*(i+1)+1] = ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+1))]*8;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
if(dx==1)//a
result += tmp_res[j][2*i+x+1]*COEF_QUART[x+1];
else//b
result += tmp_res[j][2*i+x+2]*COEF_QUART[x+1];
block[i][j] = max(0, min(255, (result+64)/128));
}
}
}
else if((dy==2) && (dx==0)){//vertical 1/2 position: 2
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
result += ref_pic[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF_HALF[y+1];
block[i][j] = max(0, min(255, (result+4)/8));
}
}
}
else if(((dy==1) || (dy==3)) && (dx==0)){//vertical 1/4 position: c and j
for (j = -1; j < B8_SIZE+1; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
result += ref_pic[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF_HALF[y+1];
tmp_res[2*(j+1)][i] = result;
tmp_res[2*(j+1)+1][i] = ref_pic[max(0,min(maxold_y,y_pos+j+1))][max(0,min(maxold_x,x_pos+i))]*8;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
if(dy==1)//c
result += tmp_res[2*j+y+1][i]*COEF_QUART[y+1];
else//j
result += tmp_res[2*j+y+2][i]*COEF_QUART[y+1];
block[i][j] = max(0, min(255, (result+64)/128));
}
}
}
else if((dx==2) && (dy==2)){//horizonal and vertical 1/2 position: 3
for (j = -1; j < B8_SIZE+2; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
result += ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF_HALF[x+1];
tmp_res[j+1][i] = result;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
result += tmp_res[j+y+1][i]*COEF_HALF[y+1];
block[i][j] = max(0, min(255, (result+32)/64));
}
}
}
else if(((dx==1) || (dx==3)) && dy==2){//horizonal and vertical 1/4 position: h and i
for (j = 0; j < B8_SIZE; j++) {
for (i = -2; i < B8_SIZE+3; i++) {
for (result = 0, y = -1; y < 3; y++)
result += ref_pic[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF_HALF[y+1];
tmp_res[j][i+2] = result;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE+2; i++) {
for (result = 0, x = -1; x < 3; x++)
result += tmp_res[j][i+1+x]*COEF_HALF[x+1];
tmp_res_2[j][2*i] = result;
tmp_res_2[j][2*i+1] = tmp_res[j][i+2]*8;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
if(dx==1)//h
result += tmp_res_2[j][2*i+x+1]*COEF_QUART[x+1];
else
result += tmp_res_2[j][2*i+x+2]*COEF_QUART[x+1];
block[i][j] = max(0, min(255, (result+512)/1024));
}
}
}
else if(((dy==1) || (dy==3)) && (dx==2)){//vertical and horizonal 1/4 position: e and l
for (j = -2; j < B8_SIZE+3; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
result += ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF_HALF[x+1];
tmp_res[j+2][i] =result;
}
}
for (j = 0; j < B8_SIZE+2; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
result += tmp_res[j+y+1][i]*COEF_HALF[y+1];
tmp_res_2[2*j][i] = result;
tmp_res_2[2*j+1][i] = tmp_res[j+2][i]*8;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
if(dy==1)//e
result += tmp_res_2[2*j+y+1][i]*COEF_QUART[y+1];
else//l
result += tmp_res_2[2*j+y+2][i]*COEF_QUART[y+1];
block[i][j] = max(0, min(255, (result+512)/1024));
}
}
}
else{//Diagonal 1/4 position : d, f, k and m
for (j = -1; j < B8_SIZE+2; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, x = -1; x < 3; x++)
result += ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF_HALF[x+1];
tmp_res[j+1][i] = result;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
for (result = 0, y = -1; y < 3; y++)
result += tmp_res[j+y+1][i]*COEF_HALF[y+1];
tmp_res_2[j][i] = result;
}
}
for (j = 0; j < B8_SIZE; j++) {
for (i = 0; i < B8_SIZE; i++) {
if((dx==1) && (dy==1))//d
result = tmp_res_2[j][i]+ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i))]*64;
else if((dx==3) && (dy==1))//f
result = tmp_res_2[j][i]+ref_pic[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+1))]*64;
else if((dx==1) && (dy==3))//k
result = tmp_res_2[j][i]+ref_pic[max(0,min(maxold_y,y_pos+j+1))][max(0,min(maxold_x,x_pos+i))]*64;
else if((dx==3) && (dy==3))//m
result = tmp_res_2[j][i]+ref_pic[max(0,min(maxold_y,y_pos+j+1))][max(0,min(maxold_x,x_pos+i+1))]*64;
block[i][j] = max(0, min(255, (result+64)/128));
}
}
}
}
}
/*
*************************************************************************
* Function:Reads new slice from bit_stream
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int Header()
{
unsigned char *Buf;
int startcodepos,length;
#ifdef FLEXPICHEAD
int temp;
#endif
#ifdef ERROR_CONTROL
//错误保护
static int first = 1;
if(first)
{
prevPictureheaderloss = 0;
first = 0;
}
#endif
if ((Buf = (char*)calloc (MAX_CODED_FRAME_SIZE , sizeof(char))) == NULL)
no_mem_exit("GetAnnexbNALU: Buf");
while (1)
{
#ifdef ERROR_CONTROL
//核心帧
if ( prevPictureheaderloss == 1 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -