1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: quality_monitor.cpp,v 1.33 2008/08/14 01:04:26 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s): Thomas Davies (Original Author)
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
35 * or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37
38 #include <libdirac_encoder/quality_monitor.h>
39 #include <libdirac_common/wavelet_utils.h>
40 using namespace dirac;
41
42 using std::log10;
43
QualityMonitor(EncoderParams & encp)44 QualityMonitor::QualityMonitor(EncoderParams& encp) :
45 m_encparams(encp),
46 m_mse_averageY(3),
47 m_mse_averageU(3),
48 m_mse_averageV(3),
49 m_picture_total(3)
50 {
51 ResetAll();
52 }
53
~QualityMonitor()54 QualityMonitor::~QualityMonitor()
55 {}
56
ResetAll()57 void QualityMonitor::ResetAll()
58 {
59
60 for (int i=0; i<3 ; ++i )
61 {
62 m_mse_averageY[i] = 0.0;
63 m_mse_averageU[i] = 0.0;
64 m_mse_averageV[i] = 0.0;
65 m_picture_total[i] = 0;
66 }// i
67 m_totalmse_averageY = 0.0;
68 m_totalmse_averageU = 0.0;
69 m_totalmse_averageV = 0.0;
70 m_allpicture_total = 0;
71 }
72
WriteLog()73 void QualityMonitor::WriteLog()
74 {
75 const double Ymax = double( (1<<m_encparams.LumaDepth())-1 );
76 const double UVmax = double( (1<<m_encparams.ChromaDepth())-1 );
77
78 std::cout<<std::endl<<"Overall mean PSNR values";
79 std::cout<<std::endl<<"------------------------";
80 std::cout<<std::endl<<"Y: ";
81 std::cout.width(5);std::cout.precision(4);
82 std::cout<<10*std::log10(Ymax*Ymax/(m_totalmse_averageY/m_allpicture_total))<<std::endl;
83 std::cout<<std::endl<<"U: ";
84 std::cout.width(5);std::cout.precision(4);
85 std::cout<<10*std::log10(UVmax*UVmax/(m_totalmse_averageU/m_allpicture_total))<<std::endl;
86 std::cout<<std::endl<<"V: ";
87 std::cout.width(5);std::cout.precision(4);
88 std::cout<<10*std::log10(UVmax*UVmax/(m_totalmse_averageV/m_allpicture_total))<<std::endl;
89
90
91 std::cout<<std::endl<<"Mean PSNR values by picture type and component";
92 std::cout<<std::endl<<"--------------------------------------------";
93 std::cout<<std::endl;
94
95 std::cout<<std::endl<<" || Y || U || V ||";
96 std::cout<<std::endl<<"=================||===================================================";
97 std::cout<<std::endl<<" Intra || ";
98 std::cout.width(5);std::cout.precision(4);
99 std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[0]/m_picture_total[0]))<<" || ";
100 std::cout.width(5);std::cout.precision(4);
101 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[0]/m_picture_total[0]))<<" || ";
102 std::cout.width(5);std::cout.precision(4);
103 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[0]/m_picture_total[0]))<<" || ";
104 std::cout<<std::endl<<"-----------------||---------------------------------------------------";
105 std::cout<<std::endl<<" Inter Ref || ";
106 std::cout.width(5);std::cout.precision(4);
107 std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[1]/m_picture_total[1]))<<" || ";
108 std::cout.width(5);std::cout.precision(4);
109 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[1]/m_picture_total[1]))<<" || ";
110 std::cout.width(5);std::cout.precision(4);
111 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[1]/m_picture_total[1]))<<" || ";
112 std::cout<<std::endl<<"-----------------||---------------------------------------------------";
113 std::cout<<std::endl<<" Inter Non Ref || ";
114 std::cout.width(5);std::cout.precision(4);
115 std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[2]/m_picture_total[2]))<<" || ";
116 std::cout.width(5);std::cout.precision(4);
117 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[2]/m_picture_total[2]))<<" || ";
118 std::cout.width(5);std::cout.precision(4);
119 std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[2]/m_picture_total[2]))<<" || ";
120 std::cout<<std::endl<<"-----------------||---------------------------------------------------";
121 }
122
UpdateModel(const EncPicture & enc_picture)123 void QualityMonitor::UpdateModel(const EncPicture& enc_picture )
124 {
125 const double Ymax = double( (1<<m_encparams.LumaDepth())-1 );
126 const double UVmax = double( (1<<m_encparams.ChromaDepth())-1 );
127
128 const PictureSort& psort = enc_picture.GetPparams().PicSort();
129 int idx = psort.IsIntra() ? 0 : (psort.IsRef() ? 1 : 2);
130
131 double fmseY, fmseU, fmseV;
132
133 fmseY = QualityVal( enc_picture.Data(Y_COMP) , enc_picture.OrigData(Y_COMP),
134 m_encparams.Xl(), m_encparams.Yl());
135 m_mse_averageY[idx] += fmseY;
136 m_totalmse_averageY += fmseY;
137
138 fmseU = QualityVal( enc_picture.Data(U_COMP) , enc_picture.OrigData(U_COMP),
139 m_encparams.ChromaXl(),
140 m_encparams.ChromaYl());
141 m_mse_averageU[idx] += fmseU;
142 m_totalmse_averageU += fmseU;
143
144 fmseV = QualityVal( enc_picture.Data(V_COMP) , enc_picture.OrigData(V_COMP),
145 m_encparams.ChromaXl(),
146 m_encparams.ChromaYl());
147 m_mse_averageV[idx] += fmseV;
148 m_totalmse_averageV += fmseV;
149
150 m_picture_total[idx]++;
151 m_allpicture_total++;
152
153 if (m_encparams.Verbose() )
154 {
155 std::cout<<std::endl<< (!m_encparams.FieldCoding() ? "Frame" : "Field");
156 std::cout << " PSNR: Y="<<10.0 * std::log10( Ymax*Ymax / fmseY );
157 std::cout<<", U="<<10.0 * std::log10( UVmax*UVmax / fmseU );
158 std::cout<<", V="<<10.0 * std::log10( UVmax*UVmax / fmseV );
159 }
160
161 }
162
163
QualityVal(const PicArray & coded_data,const PicArray & orig_data,const int xlen,const int ylen)164 double QualityMonitor::QualityVal(const PicArray& coded_data,
165 const PicArray& orig_data,
166 const int xlen, const int ylen)
167 {
168 long double sum_sq_diff = 0.0;
169 double diff;
170 for ( int j=0;j<ylen; ++j )
171 {
172 for ( int i=0;i<xlen; ++i )
173 {
174 diff = orig_data[j][i] - coded_data[j][i];
175 sum_sq_diff += diff*diff;
176
177 }// i
178 }// j
179
180
181 sum_sq_diff /= xlen*ylen;
182
183 return (double) sum_sq_diff;
184 }
185