1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: common.cpp,v 1.80 2009/01/21 05:21:27 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 *                 Scott R Ladd,
25 *                 Tim Borer,
26 *                 Anuradha Suraparaju,
27 *                 Andrew Kennedy
28 *                 Myo Tun (Brunel University, myo.tun@brunel.ac.uk)
29 *
30 * Alternatively, the contents of this file may be used under the terms of
31 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
32 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
33 * the GPL or the LGPL are applicable instead of those above. If you wish to
34 * allow use of your version of this file only under the terms of the either
35 * the GPL or LGPL and not to allow others to use your version of this file
36 * under the MPL, indicate your decision by deleting the provisions above
37 * and replace them with the notice and other provisions required by the GPL
38 * or LGPL. If you do not delete the provisions above, a recipient may use
39 * your version of this file under the terms of any one of the MPL, the GPL
40 * or the LGPL.
41 * ***** END LICENSE BLOCK ***** */
42 
43 #include <algorithm>
44 #include <sstream>
45 #ifndef _MSC_VER
46 #include <inttypes.h>
47 #endif
48 #include <libdirac_common/common.h>
49 #include <libdirac_common/video_format_defaults.h>
50 #include <libdirac_common/dirac_exception.h>
51 using namespace dirac;
52 
53 
54 //const dirac::QuantiserLists dirac::dirac_quantiser_lists;
55 
56 
57 //EntropyCorrector functions
58 
EntropyCorrector(int depth)59 EntropyCorrector::EntropyCorrector(int depth):
60     m_Yfctrs( 3 , 3*depth+1 ),
61     m_Ufctrs( 3 , 3*depth+1 ),
62     m_Vfctrs( 3 , 3*depth+1 )
63 {
64     Init();
65 }
66 
Factor(const int bandnum,const PictureParams & pp,const CompSort c) const67 float EntropyCorrector::Factor(const int bandnum , const PictureParams& pp ,
68                                const CompSort c) const
69 {
70     int idx = pp.PicSort().IsIntra() ? 0 : (pp.IsBPicture() ? 1 : 2);
71     if (c == U_COMP)
72         return m_Ufctrs[idx][bandnum-1];
73     else if (c == V_COMP)
74         return m_Vfctrs[idx][bandnum-1];
75     else
76         return m_Yfctrs[idx][bandnum-1];
77 }
78 
Init()79 void EntropyCorrector::Init()
80 {
81 
82     //do I-pictures
83     for (int  i=0 ; i<m_Yfctrs.LengthX() ; ++i )
84     {
85         if ( i == m_Yfctrs.LastX() )
86         {
87             // Set factor for Intra pictures
88             m_Yfctrs[0][i] = 1.0f;
89             m_Ufctrs[0][i] = 1.0f;
90             m_Vfctrs[0][i] = 1.0f;
91             // Set factor for Inter Ref pictures
92             m_Yfctrs[1][i] = 0.85f;
93             m_Ufctrs[1][i] = 0.85f;
94             m_Vfctrs[1][i] = 0.85f;
95             // Set factor for Inter Non-Ref pictures
96             m_Yfctrs[2][i] = 0.85f;
97             m_Ufctrs[2][i] = 0.85f;
98             m_Vfctrs[2][i] = 0.85f;
99         }
100         else if ( i >= m_Yfctrs.LastX()-3 )
101         {
102             // Set factor for Intra pictures
103             m_Yfctrs[0][i] = 0.85f;
104             m_Ufctrs[0][i] = 0.85f;
105             m_Vfctrs[0][i] = 0.85f;
106             // Set factor for Inter Ref pictures
107             m_Yfctrs[1][i] = 0.75f;
108             m_Ufctrs[1][i] = 0.75f;
109             m_Vfctrs[1][i] = 0.75f;
110             // Set factor for Inter Non-Ref pictures
111             m_Yfctrs[2][i] = 0.75f;
112             m_Ufctrs[2][i] = 0.75f;
113             m_Vfctrs[2][i] = 0.75f;
114         }
115         else
116         {
117             // Set factor for Intra pictures
118             m_Yfctrs[0][i] = 0.75f;
119             m_Ufctrs[0][i] = 0.75f;
120             m_Vfctrs[0][i] = 0.75f;
121             // Set factor for Inter Ref pictures
122             m_Yfctrs[1][i] = 0.75f;
123             m_Ufctrs[1][i] = 0.75f;
124             m_Vfctrs[1][i] = 0.75f;
125             // Set factor for Inter Non-Ref pictures
126             m_Yfctrs[2][i] = 0.75f;
127             m_Ufctrs[2][i] = 0.75f;
128             m_Vfctrs[2][i] = 0.75f;
129         }
130     }//i
131 
132 }
133 
Update(int bandnum,const PictureParams & pp,CompSort c,int est_bits,int actual_bits)134 void EntropyCorrector::Update(int bandnum , const PictureParams& pp ,
135                        CompSort c ,int est_bits , int actual_bits){
136     //updates the factors - note that the estimated bits are assumed to already include the correction factor
137 
138     float multiplier;
139     if (actual_bits != 0 && est_bits != 0)
140         multiplier = float(actual_bits)/float(est_bits);
141     else
142         multiplier=1.0;
143 
144     int idx = pp.PicSort().IsIntra() ? 0 : (pp.IsBPicture() ? 1 : 2);
145     if (c == U_COMP)
146         m_Ufctrs[idx][bandnum-1] *= multiplier;
147     else if (c == V_COMP)
148         m_Vfctrs[idx][bandnum-1] *= multiplier;
149     else
150         m_Yfctrs[idx][bandnum-1] *= multiplier;
151 }
152 
153 // Overlapped block parameter functions
154 
OLBParams(const int xblen,int const yblen,int const xbsep,int const ybsep)155 OLBParams::OLBParams(const int xblen, int const yblen, int const xbsep, int const ybsep):
156     m_xblen(xblen),
157     m_yblen(yblen),
158     m_xbsep(xbsep),
159     m_ybsep(ybsep),
160     m_xoffset( (xblen-xbsep)/2 ),
161     m_yoffset( (yblen-ybsep)/2 )
162 {}
163 
operator ==(const OLBParams bparams) const164 bool OLBParams::operator ==(const OLBParams bparams) const
165 {
166     if (bparams.Xblen() != m_xblen ||
167         bparams.Yblen() != m_yblen ||
168         bparams.Xbsep() != m_xbsep ||
169         bparams.Ybsep() != m_ybsep)
170 
171         return false;
172 
173     return true;
174 }
175 
176 namespace dirac
177 {
operator <<(std::ostream & stream,OLBParams & params)178 std::ostream & operator<< (std::ostream & stream, OLBParams & params)
179 {
180     stream << params.Ybsep() << " " << params.Xbsep();
181 //     stream << " " <<params.Yblen() << " " << params.Xblen();
182 
183     return stream;
184 }
185 
operator >>(std::istream & stream,OLBParams & params)186 std::istream & operator>> (std::istream & stream, OLBParams & params)
187 {
188     int temp;
189 
190     stream >> temp;
191     params.SetYbsep(temp);
192 
193     stream >> temp;
194     params.SetXbsep(temp);
195 
196 //     stream >> temp;
197 //     params.SetYblen(temp);
198 
199 //     stream >> temp;
200 //     params.SetXblen(temp);
201 
202     return stream;
203 }
204 
205 }
206 
SetBlockSizes(const OLBParams & olbparams,const ChromaFormat cformat)207 void PicturePredParams::SetBlockSizes(const OLBParams& olbparams , const ChromaFormat cformat)
208 {
209     //given the raw overlapped block parameters, set the modified internal parameters to
210     //take account of the chroma sampling format and overlapping requirements, as well
211     //as the equivalent parameters for sub-SBs and SBs.
212     //Does NOT set the number of blocks or superblocks, as padding may be required.
213 
214     OLBParams tmp_olbparams = olbparams;
215     // Factors for scaling chroma blocks
216     int xcfactor,ycfactor;
217 
218     if (cformat == format420)
219     {
220         xcfactor = 2;
221         ycfactor = 2;
222     }
223     else if (cformat == format422)
224     {
225         xcfactor = 2;
226         ycfactor = 1;
227     }
228     else
229     {// assume 444
230         xcfactor = 1;
231         ycfactor = 1;
232     }
233 
234 
235     m_lbparams[2] = tmp_olbparams;
236 
237     // Check separations are all divisible by 4
238     int remainder= m_lbparams[2].Xbsep()%4;
239     if ( remainder!=0 || m_lbparams[2].Xbsep()==0 )
240     {
241         m_lbparams[2].SetXbsep( m_lbparams[2].Xbsep()+(4-remainder));
242         m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4 );
243     }
244     remainder= m_lbparams[2].Ybsep()%4;
245     if ( remainder!=0 || m_lbparams[2].Ybsep()==0 )
246     {
247         m_lbparams[2].SetYbsep( m_lbparams[2].Ybsep()+(4-remainder));
248         m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4 );
249 
250     }
251 
252     // Now check lengths are divisible by 4
253     remainder= m_lbparams[2].Xblen()%4;
254     if ( remainder!=0 )
255     {
256         m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
257     }
258     remainder= m_lbparams[2].Yblen()%4;
259     if ( remainder!=0 )
260     {
261         m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
262     }
263 
264     // Check there's non-negative overlap,
265     // XBLEN >= XBSEP, YBLEN >= YBSEP
266     if (m_lbparams[2].Xbsep()>m_lbparams[2].Xblen())
267     {
268         m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
269     }
270     if (m_lbparams[2].Ybsep()>m_lbparams[2].Yblen())
271     {
272         m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
273     }
274 
275     // Check the lengths aren't too big (100% is max roll-off)
276     // XBLEN <= 2*XBSEP, YBLEN <= 2*YBSEP
277     if (2*m_lbparams[2].Xbsep()<m_lbparams[2].Xblen())
278     {
279         m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
280     }
281     if (2*m_lbparams[2].Ybsep()<m_lbparams[2].Yblen())
282     {
283         m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
284     }
285 
286     // Set the chroma values
287     m_cbparams[2].SetXbsep( m_lbparams[2].Xbsep()/xcfactor );
288     m_cbparams[2].SetXblen( m_lbparams[2].Xblen()/xcfactor );
289     m_cbparams[2].SetYbsep( m_lbparams[2].Ybsep()/ycfactor );
290     m_cbparams[2].SetYblen( m_lbparams[2].Yblen()/ycfactor );
291 
292 
293     //Now work out the overlaps for splitting levels 1 and 0
294     m_lbparams[1].SetXbsep( m_lbparams[2].Xbsep()*2 );
295     m_lbparams[1].SetXblen( m_lbparams[2].Xblen() + m_lbparams[2].Xbsep() );
296     m_lbparams[1].SetYbsep( m_lbparams[2].Ybsep()*2 );
297     m_lbparams[1].SetYblen( m_lbparams[2].Yblen() + m_lbparams[2].Xbsep() );
298 
299     m_lbparams[0].SetXbsep( m_lbparams[1].Xbsep()*2 );
300     m_lbparams[0].SetXblen( m_lbparams[1].Xblen() + m_lbparams[1].Xbsep() );
301     m_lbparams[0].SetYbsep( m_lbparams[1].Ybsep()*2 );
302     m_lbparams[0].SetYblen( m_lbparams[1].Yblen() + m_lbparams[1].Xbsep() );
303 
304     m_cbparams[1].SetXbsep( m_cbparams[2].Xbsep()*2 );
305     m_cbparams[1].SetXblen( m_cbparams[2].Xblen() + m_cbparams[2].Xbsep() );
306     m_cbparams[1].SetYbsep( m_cbparams[2].Ybsep()*2 );
307     m_cbparams[1].SetYblen( m_cbparams[2].Yblen() + m_cbparams[2].Xbsep() );
308 
309     m_cbparams[0].SetXbsep( m_cbparams[1].Xbsep()*2 );
310     m_cbparams[0].SetXblen( m_cbparams[1].Xblen() + m_cbparams[1].Xbsep() );
311     m_cbparams[0].SetYbsep( m_cbparams[1].Ybsep()*2 );
312     m_cbparams[0].SetYblen( m_cbparams[1].Yblen() + m_cbparams[1].Xbsep() );
313 
314     if ( m_lbparams[2].Xbsep()!=olbparams.Xbsep() ||
315          m_lbparams[2].Ybsep()!=olbparams.Ybsep() ||
316          m_lbparams[2].Xblen()!=olbparams.Xblen() ||
317          m_lbparams[2].Yblen()!=olbparams.Yblen() )
318     {
319         std::cout<<std::endl<<"WARNING: block parameters are inconsistent with ";
320         std::cout<<"specification requirements, which are:";
321         std::cout<<std::endl<<"\t 1. Lengths and separations must be positive multiples of 4";
322         std::cout<<std::endl<<"\t 2. Length can't be more than twice separations";
323         std::cout<<std::endl<<"\t 3. Lengths must be greater than or equal to separations";
324         std::cout<<std::endl<<std::endl<<"Instead, using:";
325         std::cout<<" xblen="<<m_lbparams[2].Xblen();
326         std::cout<<" yblen="<<m_lbparams[2].Yblen();
327         std::cout<<" xbsep="<<m_lbparams[2].Xbsep();
328         std::cout<<" ybsep="<<m_lbparams[2].Ybsep() << std::endl;
329     }
330 }
331 
332 
333 // Codec params functions
334 
CodecParams(const VideoFormat & vd,PictureType ftype,unsigned int num_refs,bool set_defaults)335 CodecParams::CodecParams(const VideoFormat &vd, PictureType ftype, unsigned int num_refs, bool set_defaults):
336    m_video_format(vd)
337 {
338     if (set_defaults)
339         SetDefaultCodecParameters(*this, ftype, num_refs);
340 }
341 
TransformFilter(unsigned int wf_idx)342 WltFilter CodecParams::TransformFilter (unsigned int wf_idx)
343 {
344     if (wf_idx >= filterNK)
345         DIRAC_THROW_EXCEPTION(
346             ERR_UNSUPPORTED_STREAM_DATA,
347             "Wavelet filter idx out of range [0-7]",
348             SEVERITY_PICTURE_ERROR);
349 
350     if (wf_idx==FIDELITY)
351     {
352         std::ostringstream errstr;
353         errstr << "Wavelet Filter " << wf_idx << " currently not supported";
354         DIRAC_THROW_EXCEPTION(
355             ERR_UNSUPPORTED_STREAM_DATA,
356             errstr.str(),
357             SEVERITY_PICTURE_ERROR);
358     }
359     return static_cast<WltFilter>(wf_idx);
360 }
361 
SetTransformFilter(unsigned int wf_idx)362 void CodecParams::SetTransformFilter(unsigned int wf_idx)
363 {
364     SetTransformFilter(TransformFilter(wf_idx));
365 }
366 
SetTransformDepth(unsigned int wd)367 void CodecParams::SetTransformDepth (unsigned int wd)
368 {
369     m_wlt_depth = wd;
370     // Resize the code block size array.
371     m_cb.Resize(wd+1);
372 }
373 
SetCodeBlocks(unsigned int level,unsigned int hblocks,unsigned int vblocks)374 void CodecParams::SetCodeBlocks (unsigned int level,
375                                    unsigned int hblocks,
376                                    unsigned int vblocks)
377 {
378     if (level > m_wlt_depth)
379     {
380         std::ostringstream errstr;
381         errstr << "level " << level << " out of range [0-" << m_wlt_depth  << "]";
382         DIRAC_THROW_EXCEPTION(
383             ERR_UNSUPPORTED_STREAM_DATA,
384             errstr.str(),
385             SEVERITY_PICTURE_ERROR);
386     }
387 
388     m_cb[level].SetHorizontalCodeBlocks(hblocks);
389     m_cb[level].SetVerticalCodeBlocks(vblocks);
390 }
391 
GetCodeBlocks(unsigned int level) const392 const CodeBlocks &CodecParams::GetCodeBlocks (unsigned int level) const
393 {
394     if (level > m_wlt_depth)
395     {
396         std::ostringstream errstr;
397         errstr << "level " << level << " out of range [0-" << m_wlt_depth  << "]";
398         DIRAC_THROW_EXCEPTION(
399             ERR_UNSUPPORTED_STREAM_DATA,
400             errstr.str(),
401             SEVERITY_PICTURE_ERROR);
402     }
403 
404     return m_cb[level];
405 }
406 
SetCodeBlockMode(unsigned int cb_mode)407 void CodecParams::SetCodeBlockMode (unsigned int cb_mode)
408 {
409     if (cb_mode >= QUANT_UNDEF)
410     {
411         std::ostringstream errstr;
412         errstr << "Code Block mode " << cb_mode << " out of supported range [0-" << QUANT_MULTIPLE  << "]";
413         DIRAC_THROW_EXCEPTION(
414             ERR_UNSUPPORTED_STREAM_DATA,
415             errstr.str(),
416             SEVERITY_PICTURE_ERROR);
417     }
418 
419     m_cb_mode = static_cast<CodeBlockMode>(cb_mode);
420 }
421 
422 //EncoderParams functions
423 
424 //Default constructor
EncoderParams(const VideoFormat & video_format,PictureType ftype,unsigned int num_refs,bool set_defaults)425 EncoderParams::EncoderParams(const VideoFormat& video_format,
426                              PictureType ftype,
427                              unsigned int num_refs,
428                              bool set_defaults):
429     CodecParams(video_format, ftype, num_refs, set_defaults),
430     m_verbose(false),
431     m_loc_decode(true),
432     m_full_search(false),
433     m_x_range_me(32),
434     m_y_range_me(32),
435     m_ufactor(1.0),
436     m_vfactor(1.0),
437     m_prefilter(NO_PF),
438     m_prefilter_strength(0),
439     m_I_lambda(0.0f),
440     m_L1_lambda(0.f),
441     m_L2_lambda(0.0f),
442     m_L1_me_lambda(0.0f),
443     m_L2_me_lambda(0.0f),
444     m_ent_correct(0),
445     m_target_rate(0)
446 {
447     if(set_defaults)
448         SetDefaultEncoderParameters(*this);
449 }
450 
CalcLambdas(const float qf)451 void EncoderParams::CalcLambdas(const float qf)
452 {
453     if (!m_lossless )
454     {
455         m_I_lambda = std::pow( 10.0 , (12.0-qf )/2.5 )/16.0;
456 
457         m_L1_lambda = m_I_lambda*4.0;
458         m_L2_lambda = m_I_lambda*32.0;
459 
460         // Set the lambdas for motion estimation
461         const double me_ratio = 2.0;
462 
463         // Use the same ME lambda for L1 and L2 pictures
464         m_L1_me_lambda = std::sqrt(m_L1_lambda)*me_ratio;
465         m_L2_me_lambda = m_L1_me_lambda;
466     }
467     else
468     {
469         m_I_lambda = 0.0;
470         m_L1_lambda = 0.0;
471         m_L2_lambda = 0.0;
472 
473         m_L1_me_lambda = 0.0;
474         m_L2_me_lambda = 0.0;
475     }
476 }
477 
SetIntraTransformFilter(unsigned int wf_idx)478 void EncoderParams::SetIntraTransformFilter(unsigned int wf_idx)
479 {
480     SetIntraTransformFilter(TransformFilter(wf_idx));
481 }
482 
SetInterTransformFilter(unsigned int wf_idx)483 void EncoderParams::SetInterTransformFilter(unsigned int wf_idx)
484 {
485     SetInterTransformFilter(TransformFilter(wf_idx));
486 }
487 
SetUsualCodeBlocks(const PictureType &)488 void EncoderParams::SetUsualCodeBlocks ( const PictureType &/*ftype*/)
489 {
490     // No subband splitting if  spatial partitioning if false
491     // Since this function is common to encoder and decoder we allow the
492     // setting of code blocks without checking if DefaultSpatialPartition is
493     // true.
494     if (SpatialPartition() == false)
495         return;
496 
497     SetCodeBlocks(0, 1, 1);
498     int depth = TransformDepth();
499     if (depth == 0)
500         return;
501 
502     int xl_pad = (Xl() + (1 << depth)-1) & ~((1 << depth)-1);
503     int yl_pad = (Yl() + (1 << depth)-1) & ~((1 << depth)-1);
504 
505     /* NB, could have different sizes based upon ftype == INTRA_PICTURE */
506     /* aim for 12x12 codeblocks in each subband, execpt the DC with 4x4 */
507     for (int i = 1; i <= depth; i++)
508         SetCodeBlocks(depth-i+1, std::max(1,(xl_pad >> i) /12), std::max(1, (yl_pad >> i) /12));
509     SetCodeBlocks(0, std::max(1,(xl_pad >> depth) /4), std::max(1,(yl_pad >> depth) /4));
510 }
511 
GOPLength() const512 int EncoderParams::GOPLength() const
513 {
514     if (m_num_L1>0)
515         return (m_num_L1+1)*m_L1_sep;
516 
517     return ((m_num_L1==0) ? 10 : 0);
518 }
519 
DecoderParams(const VideoFormat & video_format,PictureType ftype,unsigned int num_refs,bool set_defaults)520 DecoderParams::DecoderParams(const VideoFormat& video_format,
521                              PictureType ftype,
522                              unsigned int num_refs,
523                              bool set_defaults):
524     CodecParams(video_format, ftype, num_refs, set_defaults),
525     m_verbose(false)
526 {
527 }
528 
529 // ParseParams functions
530 // constructor
ParseParams()531 ParseParams::ParseParams():
532     m_major_ver(2),
533     m_minor_ver(2),
534     m_profile(8),
535     m_level(0)
536 {}
537 
538 
539 //Source functions
540 //constructor
SourceParams(const VideoFormat & video_format,bool set_defaults)541 SourceParams::SourceParams(const VideoFormat& video_format,
542                            bool set_defaults)
543 {
544     // set default parameters
545     if(set_defaults)
546         SetDefaultSourceParameters(video_format, *this);
547 }
548 
ChromaWidth() const549 int SourceParams::ChromaWidth() const
550 {
551     switch (m_cformat)
552     {
553     case format420:
554     case format422:
555         return m_xl/2;
556 
557     case format444:
558     default:
559         return m_xl;
560     }
561 }
562 
ChromaHeight() const563 int SourceParams::ChromaHeight() const
564 {
565     switch (m_cformat)
566     {
567     case format420:
568         return m_yl/2;
569 
570     case format422:
571     case format444:
572     default:
573         return m_yl;
574     }
575 }
576 
577 
SetFrameRate(FrameRateType fr)578 void SourceParams::SetFrameRate (FrameRateType fr)
579 {
580     m_fr_idx = fr;
581     switch (fr)
582     {
583     case FRAMERATE_23p97_FPS:
584         m_framerate.m_num = 24000;
585         m_framerate.m_denom = 1001;
586         break;
587     case FRAMERATE_24_FPS:
588         m_framerate.m_num = 24;
589         m_framerate.m_denom = 1;
590         break;
591     case FRAMERATE_25_FPS:
592         m_framerate.m_num = 25;
593         m_framerate.m_denom = 1;
594         break;
595     case FRAMERATE_29p97_FPS:
596         m_framerate.m_num = 30000;
597         m_framerate.m_denom = 1001;
598         break;
599     case FRAMERATE_30_FPS:
600         m_framerate.m_num = 30;
601         m_framerate.m_denom = 1;
602         break;
603     case FRAMERATE_50_FPS:
604         m_framerate.m_num = 50;
605         m_framerate.m_denom = 1;
606         break;
607     case FRAMERATE_59p94_FPS:
608         m_framerate.m_num = 60000;
609         m_framerate.m_denom = 1001;
610         break;
611     case FRAMERATE_60_FPS:
612         m_framerate.m_num = 60;
613         m_framerate.m_denom = 1;
614         break;
615     case FRAMERATE_14p98_FPS:
616         m_framerate.m_num = 15000;
617         m_framerate.m_denom = 1001;
618         break;
619     case FRAMERATE_12p5_FPS:
620         m_framerate.m_num = 25;
621         m_framerate.m_denom = 2;
622         break;
623     default:
624         m_fr_idx = FRAMERATE_CUSTOM;
625         m_framerate.m_num = m_framerate.m_denom = 0;
626         break;
627     }
628 }
629 
SetPixelAspectRatio(PixelAspectRatioType pix_asr_idx)630 void SourceParams::SetPixelAspectRatio (PixelAspectRatioType pix_asr_idx)
631 {
632     m_pix_asr_idx = pix_asr_idx;
633 
634     switch (pix_asr_idx)
635     {
636     case PIXEL_ASPECT_RATIO_1_1:
637         m_pixel_aspect_ratio.m_num = m_pixel_aspect_ratio.m_denom = 1;
638         break;
639     case PIXEL_ASPECT_RATIO_10_11:
640         m_pixel_aspect_ratio.m_num = 10;
641         m_pixel_aspect_ratio.m_denom = 11;
642         break;
643     case PIXEL_ASPECT_RATIO_12_11:
644         m_pixel_aspect_ratio.m_num = 12;
645         m_pixel_aspect_ratio.m_denom = 11;
646         break;
647     case PIXEL_ASPECT_RATIO_40_33:
648         m_pixel_aspect_ratio.m_num = 40;
649         m_pixel_aspect_ratio.m_denom = 33;
650         break;
651     case PIXEL_ASPECT_RATIO_16_11:
652         m_pixel_aspect_ratio.m_num = 16;
653         m_pixel_aspect_ratio.m_denom = 11;
654         break;
655     case PIXEL_ASPECT_RATIO_4_3:
656         m_pixel_aspect_ratio.m_num = 4;
657         m_pixel_aspect_ratio.m_denom = 3;
658         break;
659     default:
660         m_pix_asr_idx = PIXEL_ASPECT_RATIO_CUSTOM;
661         m_pixel_aspect_ratio.m_num = m_pixel_aspect_ratio.m_denom = 0;
662         break;
663     }
664 }
665 
SetSignalRange(SignalRangeType sr)666 void SourceParams::SetSignalRange (SignalRangeType sr)
667 {
668     m_sr_idx = sr;
669     switch (sr)
670     {
671     case SIGNAL_RANGE_8BIT_FULL:
672         m_luma_offset = 0;
673         m_luma_excursion = 255;
674         m_chroma_offset = 128;
675         m_chroma_excursion = 255;
676         break;
677     case SIGNAL_RANGE_8BIT_VIDEO:
678         m_luma_offset = 16;
679         m_luma_excursion = 219;
680         m_chroma_offset = 128;
681         m_chroma_excursion = 224;
682         break;
683     case SIGNAL_RANGE_10BIT_VIDEO:
684         m_luma_offset = 64;
685         m_luma_excursion = 876;
686         m_chroma_offset = 512;
687         m_chroma_excursion = 896;
688         break;
689     case SIGNAL_RANGE_12BIT_VIDEO:
690         m_luma_offset = 256;
691         m_luma_excursion = 3504;
692         m_chroma_offset = 2048;
693         m_chroma_excursion = 3584;
694         break;
695     default:
696         m_sr_idx = SIGNAL_RANGE_CUSTOM;
697         m_luma_offset = 0;
698         m_luma_excursion = 0;
699         m_chroma_offset = 0;
700         m_chroma_excursion = 0;
701         break;
702     }
703 }
704 
SetColourSpecification(unsigned int cs_idx)705 void SourceParams::SetColourSpecification (unsigned int cs_idx)
706 {
707     m_cs_idx = cs_idx;
708     switch(cs_idx)
709     {
710     case 1:
711         m_col_primary = CP_SDTV_525;
712         m_col_matrix = CM_SDTV;
713         m_transfer_func = TF_TV;
714         break;
715     case 2:
716         m_col_primary = CP_SDTV_625;
717         m_col_matrix = CM_SDTV;
718         m_transfer_func = TF_TV;
719         break;
720     case 3:
721         m_col_primary = CP_HDTV_COMP_INTERNET;
722         m_col_matrix = CM_HDTV_COMP_INTERNET;
723         m_transfer_func = TF_TV;
724         break;
725     case 4:
726         m_col_primary = CP_DCINEMA;
727         m_col_matrix = CM_HDTV_COMP_INTERNET;
728         m_transfer_func = TF_DCINEMA;
729         break;
730     default:
731         m_cs_idx = 0;
732         m_col_primary = CP_HDTV_COMP_INTERNET;
733         m_col_matrix = CM_HDTV_COMP_INTERNET;
734         m_transfer_func = TF_TV;
735         break;
736     }
737 }
738 
SetColourPrimariesIndex(unsigned int cp)739 void SourceParams::SetColourPrimariesIndex (unsigned int cp)
740 {
741     m_cs_idx = 0;
742     if (cp >= CP_UNDEF)
743     {
744         //TODO: flag a warning
745     }
746     m_col_primary = static_cast<ColourPrimaries>(cp);
747 }
748 
SetColourMatrixIndex(unsigned int cm)749 void SourceParams::SetColourMatrixIndex (unsigned int cm)
750 {
751     m_cs_idx = 0;
752     if (cm >= CM_UNDEF)
753     {
754         //TODO: flag a warning
755     }
756     m_col_matrix = static_cast<ColourMatrix>(cm);
757 }
758 
SetTransferFunctionIndex(unsigned int tf)759 void SourceParams::SetTransferFunctionIndex (unsigned int tf)
760 {
761     m_cs_idx = 0;
762     if (tf >= TF_UNDEF)
763     {
764         //TODO: flag a warning
765     }
766     m_transfer_func = static_cast<TransferFunction>(tf);
767 }
768 
769 
770 //PictureParams functions
771 // Default constructor
PictureParams()772 PictureParams::PictureParams():
773     m_psort(PictureSort::IntraRefPictureSort()),
774     m_picture_type( INTRA_PICTURE ),
775     m_reference_type( REFERENCE_PICTURE ),
776     m_output(false),
777     m_using_ac(true)
778 {}
779 
780 // Constructor
PictureParams(const ChromaFormat & cf,int xlen,int ylen,unsigned int luma_depth,unsigned int chroma_depth)781 PictureParams::PictureParams(const ChromaFormat& cf,
782                          int xlen, int ylen,
783                          unsigned int luma_depth,
784                          unsigned int chroma_depth) :
785     m_cformat(cf),
786     m_psort(PictureSort::IntraRefPictureSort()),
787     m_picture_type( INTRA_PICTURE ),
788     m_reference_type( REFERENCE_PICTURE ),
789     m_output(false),
790     m_xl(xlen),
791     m_yl(ylen),
792     m_luma_depth(luma_depth),
793     m_chroma_depth(chroma_depth),
794     m_using_ac(true)
795 {
796     m_cxl = m_cyl = 0;
797     if (cf == format420)
798     {
799         m_cxl = xlen>>1;
800         m_cyl = ylen>>1;
801     }
802     else if (cf == format422)
803     {
804         m_cxl = xlen>>1;
805         m_cyl = ylen;
806     }
807     else if (cf == format444)
808     {
809         m_cxl = xlen;
810         m_cyl = ylen;
811     }
812 }
813 
814 // Constructor
PictureParams(const ChromaFormat & cf,const PictureSort & ps)815 PictureParams::PictureParams(const ChromaFormat& cf, const PictureSort& ps):
816     m_cformat(cf),
817     m_output(false),
818     m_using_ac(true)
819 {
820     SetPicSort( ps );
821 }
822 
PictureParams(const SourceParams & sparams)823 PictureParams::PictureParams(const SourceParams& sparams):
824     m_cformat(sparams.CFormat()),
825     m_psort(PictureSort::IntraRefPictureSort()),
826     m_picture_type( INTRA_PICTURE ),
827     m_reference_type( REFERENCE_PICTURE ),
828     m_output(false),
829     m_xl(sparams.Xl()),
830     m_yl(sparams.Yl()),
831     m_cxl(sparams.ChromaWidth()),
832     m_cyl(sparams.ChromaHeight()),
833     m_using_ac(true)
834 {
835     if (sparams.SourceSampling() == 1)
836     {
837         m_yl = (m_yl>>1);
838         m_cyl = (m_cyl>>1);
839     }
840     m_luma_depth = static_cast<unsigned int>
841          (
842              std::log((double)sparams.LumaExcursion())/std::log(2.0) + 1
843          );
844 
845     m_chroma_depth = static_cast<unsigned int>
846          (
847              std::log((double)sparams.ChromaExcursion())/std::log(2.0) + 1
848          );
849 }
850 
851 
852 
SetXl(int xlen)853 void PictureParams::SetXl(int xlen)
854 {
855     m_xl = xlen;
856     m_cxl = 0;
857     if (m_cformat == format420 || m_cformat == format422)
858     {
859         m_cxl = m_xl>>1;
860     }
861     else if (m_cformat == format444)
862     {
863         m_cxl = m_xl;
864     }
865 }
866 
SetYl(int ylen)867 void PictureParams::SetYl(int ylen)
868 {
869     m_yl = ylen;
870     m_cyl = 0;
871     if (m_cformat == format420)
872     {
873         m_cyl = m_yl>>1;
874     }
875     else if (m_cformat == format422 || m_cformat == format444)
876     {
877         m_cyl = m_yl;
878     }
879 }
880 
IsBPicture() const881 bool PictureParams::IsBPicture() const
882 {
883     bool is_B_picture( false );
884 
885     if ( m_refs.size() == 2 )
886     {
887         if ( m_refs[0] < m_fnum && m_refs[1] > m_fnum )
888             is_B_picture = true;
889 
890         if ( m_refs[0] > m_fnum && m_refs[1] < m_fnum )
891             is_B_picture = true;
892     }
893 
894     return is_B_picture;
895 }
896 
SetPicSort(const PictureSort & ps)897 void PictureParams::SetPicSort( const PictureSort& ps )
898 {
899     m_psort=ps;
900     if ( ps.IsIntra() )
901         m_picture_type = INTRA_PICTURE;
902     else
903         m_picture_type = INTER_PICTURE;
904 
905     if ( ps.IsRef() )
906         m_reference_type = REFERENCE_PICTURE;
907     else
908         m_reference_type = NON_REFERENCE_PICTURE;
909 
910 }
911 
SetPictureType(const PictureType ftype)912 void PictureParams::SetPictureType(const PictureType ftype)
913 {
914     m_picture_type = ftype;
915     if (ftype == INTRA_PICTURE )
916         m_psort.SetIntra();
917     else
918         m_psort.SetInter();
919 }
920 
SetReferenceType(const ReferenceType rtype)921 void PictureParams::SetReferenceType(const ReferenceType rtype)
922 {
923     m_reference_type = rtype;
924     if (rtype == REFERENCE_PICTURE )
925         m_psort.SetRef();
926     else
927         m_psort.SetNonRef();
928 }
929 
930 
QuantiserLists()931 QuantiserLists::QuantiserLists()
932 :
933     // FIXME: hardcode m_max_qindex to 119. In future this will depend on level
934     // As per spec max qf_idx is 127. But for values of qf_idx > 120 we
935     // will need more than 32 bits. Hence qf_idx is limited to 119.
936     m_max_qindex( 119 ),
937     m_qflist4( m_max_qindex+1 ),
938     m_intra_offset4( m_max_qindex+1 ),
939     m_inter_offset4( m_max_qindex+1 )
940 {
941     m_qflist4[0] = 4;
942     m_qflist4[1] = 5;
943     m_intra_offset4[0] = 1;
944     m_inter_offset4[0] = 1;
945     m_intra_offset4[1] = 2;
946     m_inter_offset4[1] = 2;
947 
948 #ifdef _MSC_VER
949     unsigned __int64 base, qfactor;
950 #else
951     uint64_t base, qfactor;
952 #endif //_MSC_VER
953 
954     for (unsigned int q=2; q<=m_max_qindex; ++q)
955     {
956         base = (1<<(q/4));
957 
958         switch (q%4)
959         {
960             case 0:
961                  qfactor = 4*base;
962                  break;
963             case 1:
964                  qfactor = (503829*base+52958)/105917;
965                  break;
966             case 2:
967                  qfactor = (665857*base+58854)/117708;
968                  break;
969             case 3:
970                  qfactor = (440253*base+32722)/65444;
971                  break;
972             default: //Default case never used
973                  qfactor = 0;
974         }
975 
976         m_qflist4[q] = int( qfactor );
977 
978         m_intra_offset4[q] = (m_qflist4[q]+1)>>1;
979         m_inter_offset4[q] = (3*m_qflist4[q]+4)>>3;
980     }// q
981 }
982 
983 namespace dirac
984 {
IntToVideoFormat(int video_format)985 VideoFormat IntToVideoFormat(int video_format)
986 {
987     switch(video_format)
988     {
989     case VIDEO_FORMAT_CUSTOM:
990         return VIDEO_FORMAT_CUSTOM;
991     case VIDEO_FORMAT_QSIF525:
992         return VIDEO_FORMAT_QSIF525;
993     case VIDEO_FORMAT_QCIF:
994         return VIDEO_FORMAT_QCIF;
995     case VIDEO_FORMAT_SIF525:
996         return VIDEO_FORMAT_SIF525;
997     case VIDEO_FORMAT_CIF:
998         return VIDEO_FORMAT_CIF;
999     case VIDEO_FORMAT_4CIF:
1000         return VIDEO_FORMAT_4CIF;
1001     case VIDEO_FORMAT_4SIF525:
1002         return VIDEO_FORMAT_4SIF525;
1003     case VIDEO_FORMAT_SD_480I60:
1004         return VIDEO_FORMAT_SD_480I60;
1005     case VIDEO_FORMAT_SD_576I50:
1006         return VIDEO_FORMAT_SD_576I50;
1007     case VIDEO_FORMAT_HD_720P60:
1008         return VIDEO_FORMAT_HD_720P60;
1009     case VIDEO_FORMAT_HD_720P50:
1010         return VIDEO_FORMAT_HD_720P50;
1011     case VIDEO_FORMAT_HD_1080I60:
1012         return VIDEO_FORMAT_HD_1080I60;
1013     case VIDEO_FORMAT_HD_1080I50:
1014         return VIDEO_FORMAT_HD_1080I50;
1015     case VIDEO_FORMAT_HD_1080P60:
1016         return VIDEO_FORMAT_HD_1080P60;
1017     case VIDEO_FORMAT_HD_1080P50:
1018         return VIDEO_FORMAT_HD_1080P50;
1019     case VIDEO_FORMAT_DIGI_CINEMA_2K24:
1020         return VIDEO_FORMAT_DIGI_CINEMA_2K24;
1021     case VIDEO_FORMAT_DIGI_CINEMA_4K24:
1022         return VIDEO_FORMAT_DIGI_CINEMA_4K24;
1023     case VIDEO_FORMAT_UHDTV_4K60:
1024         return VIDEO_FORMAT_UHDTV_4K60;
1025     case VIDEO_FORMAT_UHDTV_4K50:
1026         return VIDEO_FORMAT_UHDTV_4K50;
1027     case VIDEO_FORMAT_UHDTV_8K60:
1028         return VIDEO_FORMAT_UHDTV_8K60;
1029     case VIDEO_FORMAT_UHDTV_8K50:
1030         return VIDEO_FORMAT_UHDTV_8K50;
1031     default:
1032         return VIDEO_FORMAT_UNDEFINED;
1033     }
1034 }
1035 
IntToChromaFormat(int chroma_format)1036 ChromaFormat IntToChromaFormat(int chroma_format)
1037 {
1038     switch(chroma_format)
1039     {
1040     case format444:
1041         return format444;
1042     case format422:
1043         return format422;
1044     case format420:
1045         return format420;
1046     default:
1047         return formatNK;
1048     }
1049 }
1050 
IntToFrameRateType(int frame_rate_idx)1051 FrameRateType IntToFrameRateType(int frame_rate_idx)
1052 {
1053     switch(frame_rate_idx)
1054     {
1055     case FRAMERATE_CUSTOM:
1056         return FRAMERATE_CUSTOM;
1057     case FRAMERATE_23p97_FPS:
1058         return FRAMERATE_23p97_FPS;
1059     case FRAMERATE_24_FPS:
1060         return FRAMERATE_24_FPS;
1061     case FRAMERATE_25_FPS:
1062         return FRAMERATE_25_FPS;
1063     case FRAMERATE_29p97_FPS:
1064         return FRAMERATE_29p97_FPS;
1065     case FRAMERATE_30_FPS:
1066         return FRAMERATE_30_FPS;
1067     case FRAMERATE_50_FPS:
1068         return FRAMERATE_30_FPS;
1069     case FRAMERATE_59p94_FPS:
1070         return FRAMERATE_59p94_FPS;
1071     case FRAMERATE_60_FPS:
1072         return FRAMERATE_60_FPS;
1073     case FRAMERATE_14p98_FPS:
1074         return FRAMERATE_14p98_FPS;
1075     case FRAMERATE_12p5_FPS:
1076         return FRAMERATE_12p5_FPS;
1077     default:
1078         return FRAMERATE_UNDEFINED;
1079     }
1080 }
1081 
IntToPixelAspectRatioType(int pix_asr_idx)1082 PixelAspectRatioType IntToPixelAspectRatioType(int pix_asr_idx)
1083 {
1084     switch(pix_asr_idx)
1085     {
1086     case PIXEL_ASPECT_RATIO_CUSTOM:
1087         return PIXEL_ASPECT_RATIO_CUSTOM;
1088     case PIXEL_ASPECT_RATIO_1_1:
1089         return PIXEL_ASPECT_RATIO_1_1;
1090     case PIXEL_ASPECT_RATIO_10_11:
1091         return PIXEL_ASPECT_RATIO_10_11;
1092     case PIXEL_ASPECT_RATIO_12_11:
1093         return PIXEL_ASPECT_RATIO_12_11;
1094     case PIXEL_ASPECT_RATIO_40_33:
1095         return PIXEL_ASPECT_RATIO_40_33;
1096     case PIXEL_ASPECT_RATIO_16_11:
1097         return PIXEL_ASPECT_RATIO_16_11;
1098     case PIXEL_ASPECT_RATIO_4_3:
1099         return PIXEL_ASPECT_RATIO_4_3;
1100     default:
1101         return PIXEL_ASPECT_RATIO_UNDEFINED;
1102 
1103     }
1104 }
1105 
IntToSignalRangeType(int signal_range_idx)1106 SignalRangeType IntToSignalRangeType(int signal_range_idx)
1107 {
1108     switch(signal_range_idx)
1109     {
1110     case SIGNAL_RANGE_CUSTOM:
1111         return SIGNAL_RANGE_CUSTOM;
1112     case SIGNAL_RANGE_8BIT_FULL:
1113         return SIGNAL_RANGE_8BIT_FULL;
1114     case SIGNAL_RANGE_8BIT_VIDEO:
1115         return SIGNAL_RANGE_8BIT_VIDEO;
1116     case SIGNAL_RANGE_10BIT_VIDEO:
1117         return SIGNAL_RANGE_10BIT_VIDEO;
1118     case SIGNAL_RANGE_12BIT_VIDEO:
1119         return SIGNAL_RANGE_12BIT_VIDEO;
1120     default:
1121         return SIGNAL_RANGE_UNDEFINED;
1122     }
1123 }
1124 
IntToMVPrecisionType(int mv_prec)1125 MVPrecisionType IntToMVPrecisionType(int mv_prec)
1126 {
1127     switch(mv_prec)
1128     {
1129     case MV_PRECISION_PIXEL:
1130             return MV_PRECISION_PIXEL;
1131     case MV_PRECISION_HALF_PIXEL:
1132         return MV_PRECISION_HALF_PIXEL;
1133     case MV_PRECISION_QUARTER_PIXEL:
1134         return MV_PRECISION_QUARTER_PIXEL;
1135     case MV_PRECISION_EIGHTH_PIXEL:
1136         return MV_PRECISION_EIGHTH_PIXEL;
1137     default:
1138         return MV_PRECISION_UNDEFINED;
1139     }
1140 }
1141 
1142 
1143 }
1144