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