📄 image.c
字号:
/*!
*************************************************************************************
* \file
* image.c
* \brief
* Decoding a slice
* \notes:
* upadated @ June 14th 2005 according to the FCD
*************************************************************************************
*/
#include <math.h>
#include <stdlib.h>
#include <time.h>
//#include <sys/timeb.h>
#include "header.h"
#include "global.h"
#include "vlc.h"
#include "memalloc.h"
extern FILE *bits;
extern unsigned int seq_parameter_set_id;
extern unsigned int cpb_dpb_cnt_minus1;
extern unsigned int *cpb_underflow_allowable_flag;
extern unsigned int *bit_rate_value_minus1_lsb;
extern unsigned int *bit_rate_value_minus1_msb;
extern unsigned int *cpb_size_value_minus1_lsb;
extern unsigned int *cpb_size_value_minus1_msb;
extern unsigned int *dpb_size_value_minus1_lsb;
extern unsigned int *dpb_size_value_minus1_msb;
extern unsigned int *initial_cpb_removal_delay_lsb;
extern unsigned int *initial_cpb_removal_delay_msb;
extern unsigned int *initial_cpb_removal_delay;
extern unsigned int *initial_dpb_output_delay_lsb;
extern unsigned int *initial_dpb_output_delay_msb;
extern unsigned int *initial_dpb_output_delay;
extern unsigned int *Bit_Buffer;
extern unsigned int *ROT;
extern struct DecodedPictureBuffer dpb;
extern struct FrameBuffer outframe;
extern struct FrameBuffer decframe;
extern unsigned int outputtimer;
extern int pre_picture_distance;
#ifdef _HRD_
#include "HRD.h"
#endif // _HRD_
extern void UpdateiREG();
/*!
************************************************************************
* \brief
* decodes one I- or P-frame
************************************************************************
*/
int decode_one_picture(struct snr_par *snr)
{
time_t ltime1; // for time measurement
time_t ltime2;
#ifdef _HRD_
int j, i;
int framenum=0;
#endif // _HRD_
/*
#ifdef WIN32
struct _timeb tstruct1;
struct _timeb tstruct2;
#else
struct timeb tstruct1;
struct timeb tstruct2;
#endif
*/
int tmp_time; // time used by decoding the last frame
/*
#ifdef WIN32
_ftime (&tstruct1); // start time ms
#else
ftime (&tstruct1); // start time ms
#endif
time( <ime1 ); // start time s
*/
init_frame();
//cbzhu 0412
#ifdef _ISOLATED_REGION_
if(iREGenable)
{
UpdateiREG();
}
#endif //_ISOLATED_REGION_
//!< optional mode - simulate a lower-end decoder that can only decode video with low frame rate
//!< if you just want to decode the reference frames, plz active following skip_img_flag!
//!< zhan ma -- Sept 1st 2005
//if (pgImage->skip_img_flag)
// return (SOP);
decode_picture_data(); // decoding process
DeblockFrame(imgY , imgUV);
#ifdef _HRD_
{
for (j = 0; j < pgImage->height; j++)
for (i = 0; i < pgImage->width; i++)
decframe.imgY[j][i] = imgY[j][i];
for (j = 0; j < pgImage->height / 2; j++)
for (i = 0; i < pgImage->width / 2; i++)
{
decframe.imgUV[0][j][i] = imgUV[0][j][i];
decframe.imgUV[1][j][i] = imgUV[1][j][i];
}
decframe.frmnum = pgImage->number;
decframe.outputted = 0;
if (pgImage->type == I_IMG)
decframe.used_for_ref = 1;
else
{
if (!pgImage->pic_ref_flag)
decframe.used_for_ref = 1;
else
decframe.used_for_ref = 0;
}
if (pgImage->number == 0)
{
decframe.rotvalue = 0;
ROT[0] = 0;
}
else
{
if (pgImage->type == I_IMG)
ROT[pgImage->number] = ROT[pgImage->number - 1] + (pgImage->picture_distance_gap_minus1 + 1) * sps->delta_time_picture_distance_1;
else
{
ROT[pgImage->number] = ROT[pgImage->number - 1] + ((pgImage->picture_distance - pre_picture_distance) % 256) * sps->delta_time_picture_distance_1;
// added by yiwang, 2005.7.2
framenum = pgImage->picture_distance - pre_picture_distance;
}
decframe.rotvalue = ROT[pgImage->number];
pre_picture_distance = pgImage->picture_distance;
}
outputtimer += pgImage->delta_time_picture_distance_1 * framenum;
Store_OneFrame_Into_DPB(&decframe);
UpdateRefFrameBufFlag();
}
#endif // _HRD_
#if TRACE
trace_frame(p_trace,pgImage->width,pgImage->height,imgY,imgUV);
#endif
/*
#ifdef WIN32
_ftime (&tstruct2); //!< end time ms
#else
ftime (&tstruct2); //!< end time ms
#endif
*/
if (p_ref)
find_snr(snr,p_ref); //!< if ref sequence exist
time( <ime2 ); // end time sec
//tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
tot_time=tot_time + tmp_time;
report_picture(tmp_time);
write_frame(p_out);
Update_Picture_Buffers();
pgImage->number++;
return (SOP);
}
/*!
************************************************************************
* \brief
*
************************************************************************
*/
void report_picture(int time_pic)
{
#ifndef _PSNR_YUV_
if(pgImage->type == I_IMG) // I picture
//
fprintf(stdout,"%3d(I) %5d %7.4f %7.4f %7.4f %5d\n",
pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic);
//
else if(pgImage->type == P_IMG) // P pictures
fprintf(stdout,"%3d(P) %5d %7.4f %7.4f %7.4f %5d\n",
pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic);
#else
if(pgImage->type == I_IMG) // I picture
//
fprintf(stdout,"%3d(I) %5d %7.4f %7.4f %7.4f %7.4f %5d\n",
pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv,time_pic);
//
else if(pgImage->type == P_IMG) // P pictures
//
fprintf(stdout,"%3d(P) %5d %7.4f %7.4f %7.4f %7.4f %5d\n",
pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv, time_pic);
//
#endif // _PSNR_YUV_
fflush(stdout);
}
/*!
************************************************************************
* \brief
* Find PSNR for all three components.Compare decoded frame with
* the original sequence. Read input->jumpd frames to reflect frame skipping.
************************************************************************
*/
void find_snr(struct snr_par *snr, //!< pointer to snr parameters
FILE *p_ref) //!< filestream to reference YUV file
{
int i,j;
int diff_y,diff_u,diff_v;
int uv;
int status;
#ifdef _PSNR_YUV_
float tmpy, tmpu, tmpv;
#endif // _PSNR_YUV_
if(!p_ref)
{
printf("no ref file!\n");
snr->snr_u = -1;
snr->snr_u1 = -1;
snr->snr_ua = -1;
snr->snr_v = -1;
snr->snr_v1 = -1;
snr->snr_va = -1;
snr->snr_y = -1;
snr->snr_y1 = -1;
snr->snr_ya = -1;
return ;
}
rewind(p_ref);
status = fseek (p_ref, pgImage->number*pgImage->height*pgImage->width*3/2, 0);
for (j=0; j < pgImage->height; j++)
for (i=0; i < pgImage->width; i++)
{
imgY_ref[j][i]=fgetc(p_ref);
}
for (uv=0; uv < 2; uv++)
for (j=0; j < pgImage->height_cr ; j++)
for (i=0; i < pgImage->width_cr; i++)
imgUV_ref[uv][j][i]=fgetc(p_ref);
pgImage->quad[0]=0;
diff_y=0;
for (j=0; j < pgImage->height; ++j)
{
for (i=0; i < pgImage->width; ++i)
{
diff_y += pgImage->quad[abs(imgY[j][i]-imgY_ref[j][i])];
}
}
// Chroma
diff_u=0;
diff_v=0;
for (j=0; j < pgImage->height_cr; ++j)
{
for (i=0; i < pgImage->width_cr; ++i)
{
diff_u += pgImage->quad[abs(imgUV_ref[0][j][i]-imgUV[0][j][i])];
diff_v += pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])];
/*
if(pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])]!=0)//测试
{
printf("x=%d,y=%d\n",i,j);
getch();
}
*/
}
}
// Collecting SNR statistics
if (diff_y != 0)
snr->snr_y=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)diff_y)); // luma snr for current frame
if (diff_u != 0)
snr->snr_u=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_u))); // chroma snr for current frame
if (diff_v != 0)
snr->snr_v=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_v))); // chroma snr for current frame
#ifdef _PSNR_YUV_
tmpy = (float)(4.0 / pow(10, snr->snr_y / 10));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -