- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 {}