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