HEVC Test Model (HM)  HM-16.3
Debug.cpp
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2015, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
38 #include "Debug.h"
39 #include <algorithm>
40 #include <math.h>
41 #include "TComDataCU.h"
42 #include "TComPic.h"
43 #include "TComYuv.h"
44 
45 static const UInt settingNameWidth = 66;
46 static const UInt settingHelpWidth = 84;
47 static const UInt settingValueWidth = 3;
48 
49 #ifdef DEBUG_STRING
50 // these strings are used to reorder the debug output so that the encoder and decoder match.
51 const Char *debug_reorder_data_inter_token[MAX_NUM_COMPONENT+1]
52  = {"Start of channel 0 inter debug\n", "Start of channel 1 inter debug\n", "Start of channel 2 inter debug\n", "End of inter residual debug\n"} ;
53 const Char *partSizeToString[NUMBER_OF_PART_SIZES]={"2Nx2N(0)", "2NxN(1)", "Nx2N(2)", "NxN(3)", "2Nx(N/2+3N/2)(4)", "2Nx(3N/2+N/2)(5)", "(N/2+3N/2)x2N(6)", "(3N/2+N/2)x2N(7)"};
54 #endif
55 
56 // --------------------------------------------------------------------------------------------------------------------- //
57 
58 //EnvVar definition
59 
60 std::list<std::pair<std::string, std::string> > &EnvVar::getEnvVarList()
61 {
62  static std::list<std::pair<std::string, std::string> > varInfoList;
63  return varInfoList;
64 }
65 
66 std::list<EnvVar*> &EnvVar::getEnvVarInUse()
67 {
68  static std::list<EnvVar*> varInUseList;
69  return varInUseList;
70 }
71 
72 static inline Void printPair(const std::pair<std::string, std::string> &p)
73 {
74  if (p.second=="")
75  {
76  std::cout << "\n" << std::setw(settingNameWidth) << p.first << "\n" << std::endl;
77  }
78  else
79  {
80  std::cout << std::setw(settingNameWidth) << p.first << ": " << p.second << "\n" << std::endl;
81  }
82 }
83 
84 static inline Void printVal(const EnvVar* env)
85 {
86  std::cout << std::setw(settingNameWidth) << env->getName() << " = " << std::setw(settingValueWidth) << env->getInt() << " (string = " << std::setw(15) << env->getString() << ")" << std::endl;
87 }
88 
89 //static inline Bool sameEnvName( const std::pair<std::string, std::string> &a,
90 // const std::pair<std::string, std::string> &b )
91 //{
92 // // only check env name
93 // return (a.first==b.first);
94 //}
95 
97 {
98 // getEnvVarList().unique(sameEnvName);
99  if (getEnvVarList().size()!=0)
100  {
101  std::cout << "--- Environment variables:\n" << std::endl;
102  for_each(getEnvVarList().begin(), getEnvVarList().end(), printPair);
103  }
104  std::cout << std::endl;
105 }
106 
108 {
109  if (getEnvVarInUse().size()!=0)
110  {
111  std::cout << "RExt Environment variables set as follows: \n" << std::endl;
112  for_each(getEnvVarInUse().begin(), getEnvVarInUse().end(), printVal);
113  }
114  std::cout << std::endl;
115 }
116 
117 EnvVar::EnvVar(const std::string &sName, const std::string &sDefault, const std::string &sHelp) :
118  m_sName(sName),
119  m_sHelp(sHelp),
120  m_sVal(),
121  m_dVal(0),
122  m_iVal(0),
123  m_bSet(false)
124 {
125  if (getenv(m_sName.c_str()))
126  {
127  m_sVal = getenv(m_sName.c_str());
128  m_bSet = true;
129  getEnvVarInUse().push_back(this);
130  }
131  else
132  {
133  m_sVal = sDefault;
134  }
135 
136  m_dVal = strtod(m_sVal.c_str(), 0);
137  m_iVal = Int(m_dVal);
138 
139  getEnvVarList().push_back( std::pair<std::string, std::string>(m_sName, indentNewLines(lineWrap(splitOnSettings(m_sHelp), settingHelpWidth), (settingNameWidth + 4))) );
140 }
141 
142 
143 // --------------------------------------------------------------------------------------------------------------------- //
144 
145 // Debug environment variables:
146 
147 EnvVar Debug("-- Debugging","","");
148 
149 EnvVar DebugOptionList::DebugSBAC ("DEBUG_SBAC", "0", "Output debug data from SBAC entropy coder (coefficient data etc.)" );
150 EnvVar DebugOptionList::DebugRQT ("DEBUG_RQT", "0", "Output RQT debug data from entropy coder" );
151 EnvVar DebugOptionList::DebugPred ("DEBUG_PRED", "0", "Output prediction debug" );
152 EnvVar DebugOptionList::ForceLumaMode ("FORCE_LUMA_MODE", "0", "Force a particular intra direction for Luma (0-34)" );
153 EnvVar DebugOptionList::ForceChromaMode ("FORCE_CHROMA_MODE", "0", "Force a particular intra direction for chroma (0-5)" );
154 
155 #ifdef DEBUG_STRING
156 EnvVar DebugOptionList::DebugString_Structure ("DEBUG_STRUCTURE", "0", "Produce output on chosen structure bit0=intra, bit1=inter");
157 EnvVar DebugOptionList::DebugString_Pred ("DEBUG_PRED", "0", "Produce output on prediction data. bit0=intra, bit1=inter");
158 EnvVar DebugOptionList::DebugString_Resi ("DEBUG_RESI", "0", "Produce output on residual data. bit0=intra, bit1=inter");
159 EnvVar DebugOptionList::DebugString_Reco ("DEBUG_RECO", "0", "Produce output on reconstructed data. bit0=intra, bit1=inter");
160 EnvVar DebugOptionList::DebugString_InvTran ("DEBUG_INV_QT", "0", "Produce output on inverse-quantiser and transform stages. bit0=intra, bit1=inter");
161 #endif
162 
163 // --------------------------------------------------------------------------------------------------------------------- //
164 
165 //macro value printing function
166 
168 {
169  std::cout << "Non-environment-variable-controlled macros set as follows: \n" << std::endl;
170 
171  //------------------------------------------------
172 
173  //setting macros
174 
178 
180 
182 
183  //------------------------------------------------
184 
185  std::cout << std::endl;
186 }
187 
188 
189 // --------------------------------------------------------------------------------------------------------------------- //
190 
191 //Debugging
192 
196 
197 #ifdef DEBUG_ENCODER_SEARCH_BINS
198 const UInt debugEncoderSearchBinTargetLine = 0;
199 const UInt debugEncoderSearchBinWindow = 1000000;
200 #endif
201 
202 #ifdef DEBUG_CABAC_BINS
203 const UInt debugCabacBinTargetLine = 0;
204 const UInt debugCabacBinWindow = 1000000;
205 #endif
206 
208  const UInt lastY,
209  const UInt width,
210  const UInt height,
211  const UInt chan,
212  const UInt absPart,
213  const UInt scanIdx,
214  const TCoeff *const pCoeff,
215  const Bool finalEncode
216  )
217 {
218  if (DebugOptionList::DebugSBAC.getInt()!=0 && finalEncode)
219  {
220  std::cout << "Size: " << width << "x" << height << ", Last X/Y: (" << lastX << ", " << lastY << "), absPartIdx: " << absPart << ", scanIdx: " << scanIdx << ", chan: " << chan << "\n";
221  for (Int i=0; i<width*height; i++)
222  {
223  std::cout << std::setw(3) << pCoeff[i];// + dcVal;
224  if (i%width == width-1)
225  {
226  std::cout << "\n";
227  }
228  else
229  {
230  std::cout << ",";
231  }
232  }
233  std::cout << std::endl;
234  }
235 }
236 
238 {
239  const UInt CUSizeInParts = pcCU->getWidth(0)/4;
240  const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
241  for (UInt ch=0; ch<numValidComp; ch++)
242  {
243  const ComponentID compID=ComponentID(ch);
244  printf("channel: %d\n", ch);
245  for (Int y=0; y<CUSizeInParts; y++)
246  {
247  for (Int x=0; x<CUSizeInParts; x++)
248  {
249  printf(x+1==CUSizeInParts?"%3d\n":"%3d, ", pcCU->getCbf(compID)[g_auiRasterToZscan[y*CUSizeInParts + x]]);
250  }
251  }
252  }
253 }
254 
256 {
257  return (value == 0) ? 1 : (UInt(floor(log10(fabs(value)))) + ((value < 0) ? 2 : 1));
258  //for the minus sign
259 }
260 
261 UInt getZScanIndex(const UInt x, const UInt y)
262 {
263  UInt remainingX = x;
264  UInt remainingY = y;
265  UInt offset = 0;
266  UInt result = 0;
267 
268  while ((remainingX != 0) || (remainingY != 0))
269  {
270  result |= ((remainingX & 0x1) << offset) | ((remainingY & 0x1) << (offset + 1));
271 
272  remainingX >>= 1;
273  remainingY >>= 1;
274  offset += 2;
275  }
276 
277  return result;
278 }
279 
280 
281 // --------------------------------------------------------------------------------------------------------------------- //
282 
283 //String manipulation functions for aligning and wrapping printed text
284 
285 
286 std::string splitOnSettings(const std::string &input)
287 {
288  std::string result = input;
289 
290  std::string::size_type searchFromPosition = 0;
291 
292  while (searchFromPosition < result.length())
293  {
294  //find the " = " that is used to define each setting
295  std::string::size_type equalsPosition = result.find(" = ", searchFromPosition);
296 
297  if (equalsPosition == std::string::npos)
298  {
299  break;
300  }
301 
302  //then find the end of the numeric characters
303  std::string::size_type splitPosition = result.find_last_of("1234567890", equalsPosition);
304 
305  //then find the last space before the first numeric character...
306  if (splitPosition != std::string::npos)
307  {
308  splitPosition = result.find_last_of(' ', splitPosition);
309  }
310 
311  //...and replace it with a new line
312  if (splitPosition != std::string::npos)
313  {
314  result.replace(splitPosition, 1, 1, '\n');
315  }
316 
317  //start the next search from the end of the " = " string
318  searchFromPosition = (equalsPosition + 3);
319  }
320 
321  return result;
322 }
323 
324 
325 std::string lineWrap(const std::string &input, const UInt maximumLineLength)
326 {
327  if (maximumLineLength == 0)
328  {
329  return input;
330  }
331  std::string result = input;
332 
333  std::string::size_type lineStartPosition = result.find_first_not_of(' '); //don't wrap any leading spaces in the string
334 
335  while (lineStartPosition != std::string::npos)
336  {
337  //------------------------------------------------
338 
339  const std::string::size_type searchFromPosition = lineStartPosition + maximumLineLength;
340 
341  if (searchFromPosition >= result.length())
342  {
343  break;
344  }
345 
346  //------------------------------------------------
347 
348  //first check to see if there is another new line character before the maximum line length
349  //we can't use find for this unfortunately because it doesn't take both a beginning and an end for its search range
350  std::string::size_type nextLineStartPosition = std::string::npos;
351  for (std::string::size_type currentPosition = lineStartPosition; currentPosition <= searchFromPosition; currentPosition++)
352  {
353  if (result[currentPosition] == '\n')
354  {
355  nextLineStartPosition = currentPosition + 1;
356  break;
357  }
358  }
359 
360  //------------------------------------------------
361 
362  //if there ia another new line character before the maximum line length, we need to start this loop again from that position
363  if (nextLineStartPosition != std::string::npos)
364  {
365  lineStartPosition = nextLineStartPosition;
366  }
367  else
368  {
369  std::string::size_type spacePosition = std::string::npos;
370 
371  //search backwards for the last space character (must use signed Int because lineStartPosition can be 0)
372  for (Int currentPosition = Int(searchFromPosition); currentPosition >= Int(lineStartPosition); currentPosition--)
373  {
374  if (result[currentPosition] == ' ')
375  {
376  spacePosition = currentPosition;
377  break;
378  }
379  }
380 
381  //if we didn't find a space searching backwards, we must hyphenate
382  if (spacePosition == std::string::npos)
383  {
384  result.insert(searchFromPosition, "-\n");
385  lineStartPosition = searchFromPosition + 2; //make sure the next search ignores the hyphen
386  }
387  else //if we found a space to split on, replace it with a new line character
388  {
389  result.replace(spacePosition, 1, 1, '\n');
390  lineStartPosition = spacePosition + 1;
391  }
392  }
393 
394  //------------------------------------------------
395  }
396 
397  return result;
398 }
399 
400 
401 std::string indentNewLines(const std::string &input, const UInt indentBy)
402 {
403  std::string result = input;
404 
405  const std::string indentString(indentBy, ' ');
406  std::string::size_type offset = 0;
407 
408  while ((offset = result.find('\n', offset)) != std::string::npos)
409  {
410  if ((++offset) >= result.length())
411  {
412  break; //increment offset so we don't find the same \n again and do no indentation at the end
413  }
414  result.insert(offset, indentString);
415  }
416 
417  return result;
418 }
419 
420 
421 // --------------------------------------------------------------------------------------------------------------------- //
422 
423 
424 Void printBlockToStream( std::ostream &ss, const Char *pLinePrefix, TComYuv &src, const UInt numSubBlocksAcross, const UInt numSubBlocksUp, const UInt defWidth )
425 {
426  const UInt numValidComp=src.getNumberValidComponents();
427 
428  for (UInt ch=0; ch<numValidComp ; ch++)
429  {
430  const ComponentID compID = ComponentID(ch);
431  const UInt width = src.getWidth(compID);
432  const UInt height = src.getHeight(compID);
433  const UInt stride = src.getStride(compID);
434  const Pel* blkSrc = src.getAddr(compID);
435  const UInt subBlockWidth=width/numSubBlocksAcross;
436  const UInt subBlockHeight=height/numSubBlocksUp;
437 
438  ss << pLinePrefix << " compID: " << compID << "\n";
439  for (UInt y=0; y<height; y++)
440  {
441  if ((y%subBlockHeight)==0 && y!=0)
442  {
443  ss << pLinePrefix << '\n';
444  }
445 
446  ss << pLinePrefix;
447  for (UInt x=0; x<width; x++)
448  {
449  if ((x%subBlockWidth)==0 && x!=0)
450  {
451  ss << std::setw(defWidth+2) << "";
452  }
453 
454  ss << std::setw(defWidth) << blkSrc[y*stride + x] << ' ';
455  }
456  ss << '\n';
457  }
458  ss << pLinePrefix << " --- \n";
459  }
460 }
461 
462 #ifdef DEBUG_STRING
463 Int DebugStringGetPredModeMask(PredMode mode)
464 {
465  return (mode==MODE_INTRA)?1:2;
466 }
467 
468 Void DebugInterPredResiReco(std::string &sDebug, TComYuv &pred, TComYuv &resi, TComYuv &reco, Int predmode_mask)
469 {
470  if (DebugOptionList::DebugString_Pred.getInt()&predmode_mask)
471  {
472  std::stringstream ss(std::stringstream::out);
473  printBlockToStream(ss, "###inter-pred: ", pred);
474  std::string debugTmp;
475  debugTmp=ss.str();
476  sDebug=debugTmp+sDebug;
477  }
478  if (DebugOptionList::DebugString_Resi.getInt()&predmode_mask)
479  {
480  std::stringstream ss(std::stringstream::out);
481  printBlockToStream(ss, "###inter-resi: ", resi);
482  sDebug+=ss.str();
483  }
484  if (DebugOptionList::DebugString_Reco.getInt()&predmode_mask)
485  {
486  std::stringstream ss(std::stringstream::out);
487  printBlockToStream(ss, "###inter-reco: ", reco);
488  sDebug+=ss.str();
489  }
490 }
491 #endif
Bool g_printDebug
Definition: Debug.cpp:194
EnvVar Debug("-- Debugging","","")
#define RExt__DECODER_DEBUG_BIT_STATISTICS
0 (default) = decoder reports as normal, 1 = decoder produces bit usage statistics (will impact decod...
Definition: TypeDef.h:239
static std::list< std::pair< std::string, std::string > > & getEnvVarList()
Definition: Debug.cpp:60
CU data structure class.
Definition: TComDataCU.h:64
Void printMacroSettings()
Definition: Debug.cpp:167
Int getInt() const
Definition: Debug.h:84
void Void
Definition: TypeDef.h:285
UInt getDecimalWidth(const Double value)
Definition: Debug.cpp:255
#define NULL
Definition: CommonDef.h:100
general YUV buffer class (header)
#define RD_TEST_SAO_DISABLE_AT_PICTURE_LEVEL
1 = tests whether SAO should be disabled at the picture level, 0 (default) = does not apply this addi...
Definition: TypeDef.h:220
std::string lineWrap(const std::string &input, const UInt maximumLineLength)
Definition: Debug.cpp:325
char Char
Definition: TypeDef.h:291
std::string m_sHelp
Definition: Debug.h:68
unsigned int UInt
Definition: TypeDef.h:297
Short Pel
pixel type
Definition: TypeDef.h:692
static const UInt settingNameWidth
Definition: Debug.cpp:45
UInt getStride(const ComponentID id) const
Definition: TComYuv.h:197
Int getNumberValidComponents() const
Definition: TComPic.h:129
picture class (header)
UInt getHeight(const ComponentID id) const
Definition: TComYuv.h:198
#define RExt__HIGH_BIT_DEPTH_SUPPORT
0 (default) use data type definitions for 8-10 bit video, 1 = use larger data types to allow for up t...
Definition: TypeDef.h:244
UChar getCbf(UInt uiIdx, ComponentID eType)
Definition: TComDataCU.h:303
static Void printEnvVar()
Definition: Debug.cpp:96
#define O0043_BEST_EFFORT_DECODING
0 (default) = disable code related to best effort decoding, 1 = enable code relating to best effort d...
Definition: TypeDef.h:222
std::string splitOnSettings(const std::string &input)
Definition: Debug.cpp:286
Void printBlockToStream(std::ostream &ss, const Char *pLinePrefix, TComYuv &src, const UInt numSubBlocksAcross, const UInt numSubBlocksUp, const UInt defWidth)
Definition: Debug.cpp:424
UInt g_auiRasterToZscan[((1<<(6))/4)*((1<<(6))/4)]
Definition: TComRom.cpp:256
const std::string & getString() const
Definition: Debug.h:85
static const UInt settingHelpWidth
Definition: Debug.cpp:46
general YUV buffer class
Definition: TComYuv.h:54
bool Bool
Definition: TypeDef.h:286
UInt getWidth(const ComponentID id) const
Definition: TComYuv.h:199
static Void printPair(const std::pair< std::string, std::string > &p)
Definition: Debug.cpp:72
UInt getZScanIndex(const UInt x, const UInt y)
Definition: Debug.cpp:261
#define PRINT_CONSTANT(NAME, NAME_WIDTH, VALUE_WIDTH)
Definition: Debug.h:58
EnvVar(const std::string &sName, const std::string &sDefault, const std::string &sHelp)
Definition: Debug.cpp:117
Definition: Debug.h:64
static Void printVal(const EnvVar *env)
Definition: Debug.cpp:84
EnvVar ForceLumaMode
Int TCoeff
transform coefficient
Definition: TypeDef.h:693
Pel * getAddr(const ComponentID id)
Definition: TComYuv.h:148
Double m_dVal
Definition: Debug.h:70
intra-prediction mode
Definition: TypeDef.h:410
Int m_iVal
Definition: Debug.h:71
static Void printEnvVarInUse()
Definition: Debug.cpp:107
std::string m_sName
Definition: Debug.h:67
#define RExt__HIGH_PRECISION_FORWARD_TRANSFORM
0 (default) use original 6-bit transform matrices for both forward and inverse transform, 1 = use original matrices for inverse transform and high precision matrices for forward transform
Definition: TypeDef.h:263
Void * g_debugAddr
Definition: Debug.cpp:195
TComPic * getPic()
Definition: TComDataCU.h:203
Void printCbfArray(TComDataCU *pcCU)
Definition: Debug.cpp:237
Bool m_bSet
Definition: Debug.h:72
std::string indentNewLines(const std::string &input, const UInt indentBy)
Definition: Debug.cpp:401
UInt g_debugCounter
Definition: Debug.cpp:193
UChar * getWidth()
Definition: TComDataCU.h:245
int Int
Definition: TypeDef.h:296
ComponentID
Definition: TypeDef.h:368
PredMode
supported prediction type
Definition: TypeDef.h:407
Void printSBACCoeffData(const UInt lastX, const UInt lastY, const UInt width, const UInt height, const UInt chan, const UInt absPart, const UInt scanIdx, const TCoeff *const pCoeff, const Bool finalEncode)
Definition: Debug.cpp:207
std::string m_sVal
Definition: Debug.h:69
double Double
Definition: TypeDef.h:298
CU data structure (header)
static const UInt settingValueWidth
Definition: Debug.cpp:47
const std::string & getName() const
Definition: Debug.h:88
UInt getNumberValidComponents() const
Definition: TComYuv.h:201
static std::list< EnvVar * > & getEnvVarInUse()
Definition: Debug.cpp:66
EnvVar ForceChromaMode
Defines types and objects for environment-variable-based debugging and feature control.