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