00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <math.h>
00017 #include <time.h>
00018
00019 #include "global.h"
00020
00021 #include "refbuf.h"
00022 #include "mbuffer.h"
00023 #include "img_luma.h"
00024 #include "img_chroma.h"
00025 #include "intrarefresh.h"
00026 #include "fmo.h"
00027 #include "sei.h"
00028 #include "memalloc.h"
00029 #include "nalu.h"
00030 #include "ratectl.h"
00031 #include "mb_access.h"
00032 #include "md_distortion.h"
00033 #include "output.h"
00034 #include "context_ini.h"
00035 #include "conformance.h"
00036 #include "enc_statistics.h"
00037
00038 #include "q_matrix.h"
00039 #include "q_offsets.h"
00040 #include "quant4x4.h"
00041 #include "quant8x8.h"
00042 #include "wp.h"
00043 #include "input.h"
00044 #include "image.h"
00045 #include "img_distortion.h"
00046 #include "img_dist_snr.h"
00047 #include "img_dist_ssim.h"
00048 #include "img_dist_ms_ssim.h"
00049 #include "cconv_yuv2rgb.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058 void accumulate_metric(float *ave_metric, float cur_metric, int frames)
00059 {
00060 *ave_metric = (float) (*ave_metric * (frames - 1) + cur_metric) / frames;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 void accumulate_average(DistMetric *metric, int frames)
00070 {
00071 accumulate_metric(&metric->average[0], metric->value[0], frames);
00072 accumulate_metric(&metric->average[1], metric->value[1], frames);
00073 accumulate_metric(&metric->average[2], metric->value[2], frames);
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 void accumulate_avslice(DistMetric *metric, int slice_type, int frames)
00083 {
00084 accumulate_metric(&metric->avslice[slice_type][0], metric->value[0], frames);
00085 accumulate_metric(&metric->avslice[slice_type][1], metric->value[1], frames);
00086 accumulate_metric(&metric->avslice[slice_type][2], metric->value[2], frames);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 void find_distortion (ImageParameters *p_Img, InputParameters *p_Inp, ImageData *imgData)
00096 {
00097 DistortionParams *p_Dist = p_Img->p_Dist;
00098 int64 diff_cmp[3] = {0};
00099
00100
00101 if (p_Img->structure!=FRAME)
00102 {
00103
00104 diff_cmp[0] += compute_SSE(p_Img->pCurImg, p_Img->imgY_com, 0, 0, p_Inp->output.height, p_Inp->output.width);
00105
00106
00107 if (p_Img->yuv_format != YUV400)
00108 {
00109 diff_cmp[1] += compute_SSE(p_Img->pImgOrg[1], p_Img->imgUV_com[0], 0, 0, p_Inp->output.height_cr, p_Inp->output.width_cr);
00110 diff_cmp[2] += compute_SSE(p_Img->pImgOrg[2], p_Img->imgUV_com[1], 0, 0, p_Inp->output.height_cr, p_Inp->output.width_cr);
00111 }
00112 }
00113 else
00114 {
00115 if( IS_INDEPENDENT(p_Inp) )
00116 {
00117 p_Img->enc_picture = p_Img->enc_frame_picture[0];
00118 }
00119 p_Img->pCurImg = imgData->frm_data[0];
00120 p_Img->pImgOrg[0] = imgData->frm_data[0];
00121
00122
00123 diff_cmp[0] += compute_SSE(p_Img->pImgOrg[0], p_Img->enc_picture->imgY, 0, 0, p_Inp->output.height, p_Inp->output.width);
00124
00125
00126 if (p_Img->yuv_format != YUV400)
00127 {
00128 p_Img->pImgOrg[1] = imgData->frm_data[1];
00129 p_Img->pImgOrg[2] = imgData->frm_data[2];
00130
00131 diff_cmp[1] += compute_SSE(p_Img->pImgOrg[1], p_Img->enc_picture->imgUV[0], 0, 0, p_Inp->output.height_cr, p_Inp->output.width_cr);
00132 diff_cmp[2] += compute_SSE(p_Img->pImgOrg[2], p_Img->enc_picture->imgUV[1], 0, 0, p_Inp->output.height_cr, p_Inp->output.width_cr);
00133 }
00134 }
00135
00136
00137 p_Dist->metric[SSE].value[0] = (float) diff_cmp[0];
00138 p_Dist->metric[SSE].value[1] = (float) diff_cmp[1];
00139 p_Dist->metric[SSE].value[2] = (float) diff_cmp[2];
00140 }
00141
00142 void select_img(ImageParameters *p_Img, InputParameters *p_Inp, ImageStructure *imgSRC, ImageStructure *imgREF, ImageData *imgData)
00143 {
00144 if (p_Img->fld_flag != FALSE)
00145 {
00146 imgSRC->format = p_Inp->output;
00147 imgREF->format = p_Inp->output;
00148
00149 imgREF->data[0] = p_Img->pCurImg;
00150 imgSRC->data[0] = p_Img->imgY_com;
00151
00152 if (p_Img->yuv_format != YUV400)
00153 {
00154 imgREF->data[1] = p_Img->pImgOrg[1];
00155 imgREF->data[2] = p_Img->pImgOrg[2];
00156 imgSRC->data[1] = p_Img->imgUV_com[0];
00157 imgSRC->data[2] = p_Img->imgUV_com[1];
00158 }
00159 }
00160 else
00161 {
00162 imgSRC->format = p_Inp->output;
00163 imgREF->format = p_Inp->output;
00164
00165 imgREF->data[0] = imgData->frm_data[0];
00166
00167 if ((p_Inp->PicInterlace == ADAPTIVE_CODING) || IS_INDEPENDENT(p_Inp))
00168 {
00169 p_Img->enc_picture = p_Img->enc_frame_picture[0];
00170 }
00171 imgSRC->data[0] = p_Img->enc_picture->imgY;
00172
00173 if (p_Img->yuv_format != YUV400)
00174 {
00175 imgREF->data[1] = imgData->frm_data[1];
00176 imgREF->data[2] = imgData->frm_data[2];
00177
00178 imgSRC->data[1] = p_Img->enc_picture->imgUV[0];
00179 imgSRC->data[2] = p_Img->enc_picture->imgUV[1];
00180 }
00181 }
00182 }
00183
00184 void compute_distortion(ImageParameters *p_Img, InputParameters *p_Inp, ImageData *imgData)
00185 {
00186 DistortionParams *p_Dist = p_Img->p_Dist;
00187 if (p_Inp->Verbose != 0)
00188 {
00189 select_img(p_Img, p_Inp, &p_Img->imgSRC, &p_Img->imgREF, imgData);
00190
00191 find_snr (p_Img, p_Inp, &p_Img->imgREF, &p_Img->imgSRC, &p_Dist->metric[SSE], &p_Dist->metric[PSNR]);
00192 if (p_Inp->Distortion[SSIM] == 1)
00193 find_ssim (p_Img, p_Inp, &p_Img->imgREF, &p_Img->imgSRC, &p_Dist->metric[SSIM]);
00194 if (p_Inp->Distortion[MS_SSIM] == 1)
00195 find_ms_ssim(p_Img, p_Inp, &p_Img->imgREF, &p_Img->imgSRC, &p_Dist->metric[MS_SSIM]);
00196
00197 if(p_Inp->DistortionYUVtoRGB == 1)
00198 {
00199 YUVtoRGB(p_Img, &p_Img->imgREF, &p_Img->imgRGB_ref);
00200 YUVtoRGB(p_Img, &p_Img->imgSRC, &p_Img->imgRGB_src);
00201 find_snr (p_Img, p_Inp, &p_Img->imgRGB_ref, &p_Img->imgRGB_src, &p_Dist->metric[SSE_RGB], &p_Dist->metric[PSNR_RGB]);
00202 if (p_Inp->Distortion[SSIM] == 1)
00203 find_ssim (p_Img, p_Inp, &p_Img->imgRGB_ref, &p_Img->imgRGB_src, &p_Dist->metric[SSIM_RGB]);
00204 if (p_Inp->Distortion[MS_SSIM] == 1)
00205 find_ms_ssim(p_Img, p_Inp, &p_Img->imgRGB_ref, &p_Img->imgRGB_src, &p_Dist->metric[MS_SSIM_RGB]);
00206 }
00207 }
00208 }