source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/Debug.cpp @ 1263

Last change on this file since 1263 was 1259, checked in by seregin, 9 years ago

port rev 4256

File size: 16.9 KB
Line 
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
34/** \file     Debug.cpp
35    \brief    Defines types and objects for environment-variable-based debugging and feature control
36*/
37
38#include "Debug.h"
39#include <algorithm>
40#include <math.h>
41#include "TComDataCU.h"
42#include "TComPic.h"
43#include "TComYuv.h"
44
45static const UInt settingNameWidth  = 66;
46static const UInt settingHelpWidth  = 84;
47static 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.
51const 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"} ;
53const 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
60std::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
66std::list<EnvVar*> &EnvVar::getEnvVarInUse()
67{
68  static std::list<EnvVar*> varInUseList;
69  return varInUseList;
70}
71
72static 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
84static 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
96Void EnvVar::printEnvVar()
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
107Void EnvVar::printEnvVarInUse()
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
117EnvVar::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
147EnvVar Debug("-- Debugging","","");
148
149EnvVar DebugOptionList::DebugSBAC             ("DEBUG_SBAC",        "0", "Output debug data from SBAC entropy coder (coefficient data etc.)"                              );
150EnvVar DebugOptionList::DebugRQT              ("DEBUG_RQT",         "0", "Output RQT debug data from entropy coder"                                                       );
151EnvVar DebugOptionList::DebugPred             ("DEBUG_PRED",        "0", "Output prediction debug"                                                                        );
152EnvVar DebugOptionList::ForceLumaMode         ("FORCE_LUMA_MODE",   "0", "Force a particular intra direction for Luma (0-34)"                                             );
153EnvVar DebugOptionList::ForceChromaMode       ("FORCE_CHROMA_MODE", "0", "Force a particular intra direction for chroma (0-5)"                                            );
154
155#ifdef DEBUG_STRING
156EnvVar DebugOptionList::DebugString_Structure ("DEBUG_STRUCTURE",   "0", "Produce output on chosen structure                        bit0=intra, bit1=inter");
157EnvVar DebugOptionList::DebugString_Pred      ("DEBUG_PRED",        "0", "Produce output on prediction data.                        bit0=intra, bit1=inter");
158EnvVar DebugOptionList::DebugString_Resi      ("DEBUG_RESI",        "0", "Produce output on residual data.                          bit0=intra, bit1=inter");
159EnvVar DebugOptionList::DebugString_Reco      ("DEBUG_RECO",        "0", "Produce output on reconstructed data.                     bit0=intra, bit1=inter");
160EnvVar 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
167Void printMacroSettings()
168{
169  std::cout << "Non-environment-variable-controlled macros set as follows: \n" << std::endl;
170
171  //------------------------------------------------
172
173  //setting macros
174
175  PRINT_CONSTANT(RExt__DECODER_DEBUG_BIT_STATISTICS,                                settingNameWidth, settingValueWidth);
176  PRINT_CONSTANT(RExt__HIGH_BIT_DEPTH_SUPPORT,                                      settingNameWidth, settingValueWidth);
177  PRINT_CONSTANT(RExt__HIGH_PRECISION_FORWARD_TRANSFORM,                            settingNameWidth, settingValueWidth);
178
179  PRINT_CONSTANT(O0043_BEST_EFFORT_DECODING,                                        settingNameWidth, settingValueWidth);
180
181  PRINT_CONSTANT(RD_TEST_SAO_DISABLE_AT_PICTURE_LEVEL,                              settingNameWidth, settingValueWidth);
182
183  //------------------------------------------------
184
185  std::cout << std::endl;
186}
187
188
189// --------------------------------------------------------------------------------------------------------------------- //
190
191//Debugging
192
193UInt  g_debugCounter  = 0;
194Bool  g_printDebug    = false;
195Void* g_debugAddr     = NULL;
196
197#ifdef DEBUG_ENCODER_SEARCH_BINS
198const UInt debugEncoderSearchBinTargetLine = 0;
199const UInt debugEncoderSearchBinWindow     = 1000000;
200#endif
201
202#ifdef DEBUG_CABAC_BINS
203const UInt debugCabacBinTargetLine = 0;
204const UInt debugCabacBinWindow     = 1000000;
205#endif
206
207Void printSBACCoeffData(  const UInt          lastX,
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
237Void printCbfArray( TComDataCU* pcCU  )
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
255UInt getDecimalWidth(const Double value)
256{
257  return (value == 0) ? 1 : (UInt(floor(log10(fabs(value)))) + ((value < 0) ? 2 : 1));
258                                                               //for the minus sign
259}
260
261UInt 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
286std::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
325std::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
401std::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
424Void 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
463Int DebugStringGetPredModeMask(PredMode mode)
464{
465  return (mode==MODE_INTRA)?1:2;
466}
467
468Void 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
Note: See TracBrowser for help on using the repository browser.