common.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: common.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
00004 *
00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006 *
00007 * The contents of this file are subject to the Mozilla Public License
00008 * Version 1.1 (the "License"); you may not use this file except in compliance
00009 * with the License. You may obtain a copy of the License at
00010 * http://www.mozilla.org/MPL/
00011 *
00012 * Software distributed under the License is distributed on an "AS IS" basis,
00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
00014 * the specific language governing rights and limitations under the License.
00015 *
00016 * The Original Code is BBC Research and Development code.
00017 *
00018 * The Initial Developer of the Original Code is the British Broadcasting
00019 * Corporation.
00020 * Portions created by the Initial Developer are Copyright (C) 2004.
00021 * All Rights Reserved.
00022 *
00023 * Contributor(s): Thomas Davies (Original Author),
00024                   Scott R Ladd,
00025                   Tim Borer
00026 *
00027 * Alternatively, the contents of this file may be used under the terms of
00028 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00029 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00030 * the GPL or the LGPL are applicable instead of those above. If you wish to
00031 * allow use of your version of this file only under the terms of the either
00032 * the GPL or LGPL and not to allow others to use your version of this file
00033 * under the MPL, indicate your decision by deleting the provisions above
00034 * and replace them with the notice and other provisions required by the GPL
00035 * or LGPL. If you do not delete the provisions above, a recipient may use
00036 * your version of this file under the terms of any one of the MPL, the GPL
00037 * or the LGPL.
00038 * ***** END LICENSE BLOCK ***** */
00039 
00040 #include <libdirac_common/common.h>
00041 #include <algorithm>
00042 using namespace dirac;
00043 
00044 
00045 //PicArray functions
00046 
00047 PicArray::PicArray(int height, int width, CompSort cs):
00048     TwoDArray<ValueType>(height , width),
00049     m_csort(cs)
00050 {
00051          //Nothing
00052 }
00053 
00054 const CompSort& PicArray::CSort() const 
00055 {
00056     return m_csort;
00057 }
00058 
00059 void PicArray::SetCSort(const CompSort cs)
00060 {
00061     m_csort=cs;
00062 }    
00063 
00064 
00065 
00066 //EntropyCorrector functions
00067 
00068 EntropyCorrector::EntropyCorrector(int depth): 
00069     m_Yfctrs( 3 , 3*depth+1 ),
00070     m_Ufctrs( 3 , 3*depth+1 ),
00071     m_Vfctrs( 3 , 3*depth+1 )
00072 {
00073     Init();
00074 }
00075 
00076 float EntropyCorrector::Factor(const int bandnum , const FrameSort fsort ,const CompSort c) const
00077 {
00078     
00079     if (c == U_COMP)
00080         return m_Ufctrs[fsort][bandnum-1];
00081     else if (c == V_COMP)
00082         return m_Vfctrs[fsort][bandnum-1];
00083     else
00084         return m_Yfctrs[fsort][bandnum-1];
00085 }
00086 
00087 void EntropyCorrector::Init()
00088 {
00089     
00090     //do I-frames
00091     for (int  i=0 ; i<m_Yfctrs.LengthX() ; ++i )
00092     {
00093         if ( i == m_Yfctrs.LastX() )
00094         {        
00095             m_Yfctrs[I_frame][i] = 1.0;
00096             m_Ufctrs[I_frame][i] = 1.0;
00097             m_Vfctrs[I_frame][i] = 1.0;
00098             m_Yfctrs[L1_frame][i] = 0.85;
00099             m_Ufctrs[L1_frame][i] = 0.85;
00100             m_Vfctrs[L1_frame][i] = 0.85;
00101             m_Yfctrs[L2_frame][i] = 0.85;
00102             m_Ufctrs[L2_frame][i] = 0.85;
00103             m_Vfctrs[L2_frame][i] = 0.85;
00104         }
00105         else if ( i >= m_Yfctrs.LastX()-3 )
00106         {
00107             m_Yfctrs[I_frame][i] = 0.85;
00108             m_Ufctrs[I_frame][i] = 0.85;
00109             m_Vfctrs[I_frame][i] = 0.85;
00110             m_Yfctrs[L1_frame][i] = 0.75;
00111             m_Ufctrs[L1_frame][i] = 0.75;
00112             m_Vfctrs[L1_frame][i] = 0.75;
00113             m_Yfctrs[L2_frame][i] = 0.75;
00114             m_Ufctrs[L2_frame][i] = 0.75;
00115             m_Vfctrs[L2_frame][i] = 0.75;            
00116         }
00117         else
00118         {
00119             m_Yfctrs[I_frame][i] = 0.75;
00120             m_Ufctrs[I_frame][i] = 0.75;
00121             m_Vfctrs[I_frame][i] = 0.75;
00122             m_Yfctrs[L1_frame][i] = 0.75;
00123             m_Ufctrs[L1_frame][i] = 0.75;
00124             m_Vfctrs[L1_frame][i] = 0.75;
00125             m_Yfctrs[L2_frame][i] = 0.75;
00126             m_Ufctrs[L2_frame][i] = 0.75;
00127             m_Vfctrs[L2_frame][i] = 0.75;            
00128         }
00129     }//i
00130     
00131 }
00132 
00133 void EntropyCorrector::Update(int bandnum , FrameSort fsort , CompSort c ,int est_bits , int actual_bits){
00134     //updates the factors - note that the estimated bits are assumed to already include the correction factor
00135     
00136     float multiplier;
00137     if (actual_bits != 0 && est_bits != 0)
00138         multiplier = float(actual_bits)/float(est_bits);
00139     else
00140         multiplier=1.0;
00141     if (c == U_COMP)
00142         m_Ufctrs[fsort][bandnum-1] *= multiplier;
00143     else if (c == V_COMP)
00144         m_Vfctrs[fsort][bandnum-1] *= multiplier;
00145     else
00146         m_Yfctrs[fsort][bandnum-1] *= multiplier;
00147 }
00148 
00149 // Overlapped block parameter functions
00150 
00151 OLBParams::OLBParams(const int xblen, int const yblen, int const xbsep, int const ybsep):
00152     m_xblen(xblen),
00153     m_yblen(yblen),
00154     m_xbsep(xbsep),
00155     m_ybsep(ybsep),
00156     m_xoffset( (xblen-xbsep)/2 ),
00157     m_yoffset( (yblen-ybsep)/2 )
00158 {}
00159 
00160 namespace dirac
00161 {
00162 std::ostream & operator<< (std::ostream & stream, OLBParams & params)
00163 {
00164     stream << params.Ybsep() << " " << params.Xbsep();
00165 //     stream << " " <<params.Yblen() << " " << params.Xblen();
00166     
00167     return stream;
00168 }
00169 
00170 std::istream & operator>> (std::istream & stream, OLBParams & params)
00171 {
00172     int temp;
00173 
00174     stream >> temp;
00175     params.SetYbsep(temp);
00176 
00177     stream >> temp;
00178     params.SetXbsep(temp);
00179 
00180 //     stream >> temp;
00181 //     params.SetYblen(temp);
00182 
00183 //     stream >> temp;
00184 //     params.SetXblen(temp);
00185     
00186     return stream;
00187 }
00188 
00189 }
00190 
00191 // Codec params functions
00192 
00193 CodecParams::CodecParams():
00194     m_x_num_mb(0),
00195     m_y_num_mb(0),
00196     m_x_num_blocks(0),
00197     m_y_num_blocks(0),
00198     m_verbose(false),
00199     m_interlace(false),
00200     m_topfieldfirst(false),
00201     m_lbparams(3),
00202     m_cbparams(3)
00203 {}
00204 
00205 void CodecParams::SetBlockSizes(const OLBParams& olbparams , const ChromaFormat cformat)
00206 {
00207     //given the raw overlapped block parameters, set the modified internal parameters to
00208     //take account of the chroma sampling format and overlapping requirements, as well
00209     //as the equivalent parameters for sub-MBs and MBs.
00210     //Does NOT set the number of blocks or macroblocks, as padding may be required.
00211 
00212     // Factors for scaling chroma blocks
00213     int xcfactor,ycfactor; 
00214  
00215     if (cformat == format420)
00216     {
00217         xcfactor = 2;
00218         ycfactor = 2;
00219     }
00220     else if (cformat == format422)
00221     {
00222         xcfactor = 2;
00223         ycfactor = 1;
00224 
00225     }
00226     else if (cformat==format411)
00227     {
00228         xcfactor = 4;
00229         ycfactor = 1;
00230     }
00231     else
00232     {// assume 444
00233         xcfactor = 1;
00234         ycfactor = 1;
00235     }
00236 
00237     m_lbparams[2] = olbparams;
00238     
00239     // Check the separations aren't too small
00240     m_lbparams[2].SetXbsep( std::max(m_lbparams[2].Xbsep() , 4) );
00241     m_lbparams[2].SetYbsep( std::max(m_lbparams[2].Ybsep() , 4) );
00242 
00243     // Check the lengths aren't too big (100% is max roll-off)
00244     m_lbparams[2].SetXblen( std::min(m_lbparams[2].Xbsep()*2 , m_lbparams[2].Xblen()) );
00245     m_lbparams[2].SetYblen( std::min(m_lbparams[2].Ybsep()*2 , m_lbparams[2].Yblen()) );
00246     
00247     // Check overlap is divisible by 2
00248     if (( m_lbparams[2].Xblen() - m_lbparams[2].Xbsep() )%2 != 0)
00249         m_lbparams[2].SetXblen( m_lbparams[2].Xblen()-1 );
00250     if (( m_lbparams[2].Yblen() - m_lbparams[2].Ybsep() )%2 != 0)
00251         m_lbparams[2].SetYblen( m_lbparams[2].Yblen()-1 );
00252 
00253     // Check there's now sufficient overlap  
00254     m_lbparams[2].SetXblen( std::max(m_lbparams[2].Xbsep()+2 , m_lbparams[2].Xblen()) );
00255     m_lbparams[2].SetYblen( std::max(m_lbparams[2].Ybsep()+2 , m_lbparams[2].Yblen()) );
00256 
00257 
00258     // If the overlapped blocks don't work for the chroma format, we have to iterate
00259     if ( (m_lbparams[2].Xbsep()%xcfactor != 0) || (m_lbparams[2].Ybsep()%ycfactor != 0) )
00260     {
00261         OLBParams new_olbparams( m_lbparams[2] );
00262 
00263         if (m_lbparams[2].Xbsep()%xcfactor != 0)
00264             new_olbparams.SetXbsep( ( (m_lbparams[2].Xbsep()/xcfactor) + 1 )*xcfactor );
00265 
00266         if (m_lbparams[2].Ybsep()%ycfactor != 0)
00267             new_olbparams.SetYbsep( ( (m_lbparams[2].Ybsep()/ycfactor) + 1 )*ycfactor );
00268 
00269         new_olbparams.SetXblen( std::max( new_olbparams.Xbsep()+2 , olbparams.Xblen() ) );
00270         new_olbparams.SetYblen( std::max( new_olbparams.Xbsep()+2 , olbparams.Xblen() ) );
00271         
00272         SetBlockSizes( new_olbparams , cformat );
00273     }
00274     
00275     // Now compute the resulting chroma block params
00276 
00277     m_cbparams[2].SetXbsep( m_lbparams[2].Xbsep()/xcfactor );
00278     m_cbparams[2].SetYbsep( m_lbparams[2].Ybsep()/ycfactor );
00279     m_cbparams[2].SetXblen( std::max(m_lbparams[2].Xblen()/xcfactor , m_cbparams[2].Xbsep()+2) );
00280     m_cbparams[2].SetYblen( std::max(m_lbparams[2].Yblen()/ycfactor , m_cbparams[2].Ybsep()+2) );
00281     
00282     //check overlap is divisible by 2
00283     if (( m_cbparams[2].Xblen() - m_cbparams[2].Xbsep() )%2 != 0)
00284         m_cbparams[2].SetXblen( m_cbparams[2].Xblen()+1 );
00285     if (( m_cbparams[2].Yblen() - m_cbparams[2].Ybsep() )%2 != 0)
00286         m_cbparams[2].SetYblen( m_cbparams[2].Yblen()+1 );
00287     
00288     //Now work out the overlaps for splitting levels 1 and 0
00289     m_lbparams[1].SetXbsep( m_lbparams[2].Xbsep()*2 );
00290     m_lbparams[1].SetXblen( m_lbparams[2].Xblen() + m_lbparams[2].Xbsep() );
00291     m_lbparams[1].SetYbsep( m_lbparams[2].Ybsep()*2 );
00292     m_lbparams[1].SetYblen( m_lbparams[2].Yblen() + m_lbparams[2].Xbsep() );
00293     
00294     m_lbparams[0].SetXbsep( m_lbparams[1].Xbsep()*2 );
00295     m_lbparams[0].SetXblen( m_lbparams[1].Xblen() + m_lbparams[1].Xbsep() );
00296     m_lbparams[0].SetYbsep( m_lbparams[1].Ybsep()*2 );
00297     m_lbparams[0].SetYblen( m_lbparams[1].Yblen() + m_lbparams[1].Xbsep() );        
00298     
00299     m_cbparams[1].SetXbsep( m_cbparams[2].Xbsep()*2 );
00300     m_cbparams[1].SetXblen( m_cbparams[2].Xblen() + m_cbparams[2].Xbsep() );
00301     m_cbparams[1].SetYbsep( m_cbparams[2].Ybsep()*2 );
00302     m_cbparams[1].SetYblen( m_cbparams[2].Yblen() + m_cbparams[2].Xbsep() );    
00303     
00304     m_cbparams[0].SetXbsep( m_cbparams[1].Xbsep()*2 );
00305     m_cbparams[0].SetXblen( m_cbparams[1].Xblen() + m_cbparams[1].Xbsep() );
00306     m_cbparams[0].SetYbsep( m_cbparams[1].Ybsep()*2 );
00307     m_cbparams[0].SetYblen( m_cbparams[1].Yblen() + m_cbparams[1].Xbsep() );        
00308     
00309 }
00310 
00311 //EncoderParams functions
00312 
00313 //Default constructor    
00314 EncoderParams::EncoderParams():
00315     CodecParams(),
00316     m_qf(5.0),
00317     m_num_L1(0),
00318     m_L1_sep(0),
00319     m_ufactor(1.0),
00320     m_vfactor(1.0),
00321     m_cpd(20.0),
00322     m_I_lambda(0.f),
00323     m_L1_lambda(0.0f),
00324     m_L2_lambda(0.0f),
00325     m_L1_me_lambda(0.0f),
00326     m_L2_me_lambda(0.0f),
00327     m_ent_correct(0),
00328     m_bit_out(0)
00329 {}
00330 
00331 float EncoderParams::Lambda(const FrameSort& fsort) const
00332 {
00333     if (fsort == I_frame)
00334         return ILambda();
00335     else if (fsort == L1_frame)
00336         return L1Lambda();
00337     else
00338         return L2Lambda();
00339 }
00340 
00341 
00342 void EncoderParams::SetLambda(const FrameSort& fsort, const float l)
00343 {
00344     if (fsort == I_frame)
00345         SetILambda(l);
00346     else if (fsort == L1_frame)
00347         SetL1Lambda(l);
00348     else
00349         SetL2Lambda(l);
00350 }
00351 
00352 //SeqParams functions
00353 //constructor
00354 SeqParams::SeqParams():
00355     m_xl(0),
00356     m_yl(0),
00357     m_cformat(format422),
00358     m_interlace(false),
00359     m_topfieldfirst(true),
00360     m_framerate(12)
00361 {}
00362 
00363 int SeqParams::ChromaWidth() const
00364 {
00365     switch (m_cformat)
00366     {
00367     case Yonly:
00368         return 0;
00369     case format411:
00370         return m_xl/4;
00371 
00372     case format420:
00373     case format422:
00374         return m_xl/2;
00375 
00376     case format444:
00377     default:
00378         return m_xl;
00379     }
00380 }
00381 
00382 int SeqParams::ChromaHeight() const
00383 {
00384     switch (m_cformat)
00385     {
00386     case Yonly:
00387         return 0;
00388         return m_yl;
00389 
00390     case format420:
00391         return m_yl/2;
00392 
00393     case format422:
00394     case format444:
00395     case format411:
00396     default:
00397         return m_yl;
00398     }
00399 }
00400 //FrameParams functions
00401 
00402 // Default constructor
00403 FrameParams::FrameParams():
00404 m_fsort(I_frame),
00405 m_output(false)
00406 {}    
00407 
00408 // Constructor 
00409 FrameParams::FrameParams(const ChromaFormat& cf, int xlen, int ylen):
00410     m_cformat(cf),
00411     m_xl(xlen),
00412     m_yl(ylen),
00413     m_fsort(I_frame),
00414     m_output(false)
00415 {}
00416 
00417 // Constructor
00418 FrameParams::FrameParams(const ChromaFormat& cf, const FrameSort& fs):
00419     m_cformat(cf),
00420     m_fsort(fs),
00421     m_output(false)
00422 {}    
00423 
00424 // Constructor
00425 FrameParams::FrameParams(const SeqParams& sparams):
00426     m_cformat(sparams.CFormat()),
00427     m_xl(sparams.Xl()),
00428     m_yl(sparams.Yl()),
00429     m_fsort(I_frame),
00430     m_output(false)
00431 {}
00432 
00433 // Constructor
00434 FrameParams::FrameParams(const SeqParams& sparams, const FrameSort& fs):
00435     m_cformat(sparams.CFormat()),
00436     m_xl(sparams.Xl()),
00437     m_yl(sparams.Yl()),
00438     m_fsort(fs),
00439     m_output(false)
00440 {}

Generated on Tue Dec 13 14:47:12 2005 for guliverkli by  doxygen 1.4.5