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

Last change on this file since 1332 was 1286, checked in by seregin, 9 years ago

port rev 4321

File size: 16.8 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;
194
195#ifdef DEBUG_ENCODER_SEARCH_BINS
196const UInt debugEncoderSearchBinTargetLine = 0;
197const UInt debugEncoderSearchBinWindow     = 1000000;
198#endif
199
200#ifdef DEBUG_CABAC_BINS
201const UInt debugCabacBinTargetLine = 0;
202const UInt debugCabacBinWindow     = 1000000;
203#endif
204
205Void printSBACCoeffData(  const UInt          lastX,
206                          const UInt          lastY,
207                          const UInt          width,
208                          const UInt          height,
209                          const UInt          chan,
210                          const UInt          absPart,
211                          const UInt          scanIdx,
212                          const TCoeff *const pCoeff,
213                          const Bool          finalEncode
214                        )
215{
216  if (DebugOptionList::DebugSBAC.getInt()!=0 && finalEncode)
217  {
218    std::cout << "Size: " << width << "x" << height << ", Last X/Y: (" << lastX << ", " << lastY << "), absPartIdx: " << absPart << ", scanIdx: " << scanIdx << ", chan: " << chan << "\n";
219    for (Int i=0; i<width*height; i++)
220    {
221      std::cout << std::setw(3) << pCoeff[i];// + dcVal;
222      if (i%width == width-1)
223      {
224        std::cout << "\n";
225      }
226      else
227      {
228        std::cout << ",";
229      }
230    }
231    std::cout << std::endl;
232  }
233}
234
235Void printCbfArray( TComDataCU* pcCU  )
236{
237  const UInt CUSizeInParts = pcCU->getWidth(0)/4;
238  const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
239  for (UInt ch=0; ch<numValidComp; ch++)
240  {
241    const ComponentID compID=ComponentID(ch);
242    printf("channel: %d\n", ch);
243    for (Int y=0; y<CUSizeInParts; y++)
244    {
245      for (Int x=0; x<CUSizeInParts; x++)
246      {
247        printf(x+1==CUSizeInParts?"%3d\n":"%3d, ", pcCU->getCbf(compID)[g_auiRasterToZscan[y*CUSizeInParts + x]]);
248      }
249    }
250  }
251}
252
253UInt getDecimalWidth(const Double value)
254{
255  return (value == 0) ? 1 : (UInt(floor(log10(fabs(value)))) + ((value < 0) ? 2 : 1));
256                                                               //for the minus sign
257}
258
259UInt getZScanIndex(const UInt x, const UInt y)
260{
261  UInt remainingX = x;
262  UInt remainingY = y;
263  UInt offset     = 0;
264  UInt result     = 0;
265
266  while ((remainingX != 0) || (remainingY != 0))
267  {
268    result |= ((remainingX & 0x1) << offset) | ((remainingY & 0x1) << (offset + 1));
269
270    remainingX >>= 1;
271    remainingY >>= 1;
272    offset      += 2;
273  }
274
275  return result;
276}
277
278
279// --------------------------------------------------------------------------------------------------------------------- //
280
281//String manipulation functions for aligning and wrapping printed text
282
283
284std::string splitOnSettings(const std::string &input)
285{
286  std::string result = input;
287
288  std::string::size_type searchFromPosition = 0;
289
290  while (searchFromPosition < result.length())
291  {
292    //find the " = " that is used to define each setting
293    std::string::size_type equalsPosition = result.find(" = ", searchFromPosition);
294
295    if (equalsPosition == std::string::npos)
296    {
297      break;
298    }
299
300    //then find the end of the numeric characters
301    std::string::size_type splitPosition = result.find_last_of("1234567890", equalsPosition);
302
303    //then find the last space before the first numeric character...
304    if (splitPosition != std::string::npos)
305    {
306      splitPosition = result.find_last_of(' ', splitPosition);
307    }
308
309    //...and replace it with a new line
310    if (splitPosition != std::string::npos)
311    {
312      result.replace(splitPosition, 1, 1, '\n');
313    }
314
315    //start the next search from the end of the " = " string
316    searchFromPosition = (equalsPosition + 3);
317  }
318
319  return result;
320}
321
322
323std::string lineWrap(const std::string &input, const UInt maximumLineLength)
324{
325  if (maximumLineLength == 0)
326  {
327    return input;
328  }
329  std::string result = input;
330
331  std::string::size_type lineStartPosition = result.find_first_not_of(' '); //don't wrap any leading spaces in the string
332
333  while (lineStartPosition != std::string::npos)
334  {
335    //------------------------------------------------
336
337    const std::string::size_type searchFromPosition = lineStartPosition + maximumLineLength;
338
339    if (searchFromPosition >= result.length())
340    {
341      break;
342    }
343
344    //------------------------------------------------
345
346    //first check to see if there is another new line character before the maximum line length
347    //we can't use find for this unfortunately because it doesn't take both a beginning and an end for its search range
348    std::string::size_type nextLineStartPosition = std::string::npos;
349    for (std::string::size_type currentPosition = lineStartPosition; currentPosition <= searchFromPosition; currentPosition++)
350    {
351      if (result[currentPosition] == '\n')
352      {
353        nextLineStartPosition = currentPosition + 1;
354        break;
355      }
356    }
357
358    //------------------------------------------------
359
360    //if there ia another new line character before the maximum line length, we need to start this loop again from that position
361    if (nextLineStartPosition != std::string::npos)
362    {
363      lineStartPosition = nextLineStartPosition;
364    }
365    else
366    {
367      std::string::size_type spacePosition = std::string::npos;
368
369      //search backwards for the last space character (must use signed Int because lineStartPosition can be 0)
370      for (Int currentPosition = Int(searchFromPosition); currentPosition >= Int(lineStartPosition); currentPosition--)
371      {
372        if (result[currentPosition] == ' ')
373        {
374          spacePosition = currentPosition;
375          break;
376        }
377      }
378
379      //if we didn't find a space searching backwards, we must hyphenate
380      if (spacePosition == std::string::npos)
381      {
382        result.insert(searchFromPosition, "-\n");
383        lineStartPosition = searchFromPosition + 2; //make sure the next search ignores the hyphen
384      }
385      else //if we found a space to split on, replace it with a new line character
386      {
387        result.replace(spacePosition, 1, 1, '\n');
388        lineStartPosition = spacePosition + 1;
389      }
390    }
391
392    //------------------------------------------------
393  }
394
395  return result;
396}
397
398
399std::string indentNewLines(const std::string &input, const UInt indentBy)
400{
401  std::string result = input;
402
403  const std::string indentString(indentBy, ' ');
404  std::string::size_type offset = 0;
405
406  while ((offset = result.find('\n', offset)) != std::string::npos)
407  {
408    if ((++offset) >= result.length())
409    {
410      break; //increment offset so we don't find the same \n again and do no indentation at the end
411    }
412    result.insert(offset, indentString);
413  }
414
415  return result;
416}
417
418
419// --------------------------------------------------------------------------------------------------------------------- //
420
421
422Void printBlockToStream( std::ostream &ss, const Char *pLinePrefix, TComYuv &src, const UInt numSubBlocksAcross, const UInt numSubBlocksUp, const UInt defWidth )
423{
424  const UInt numValidComp=src.getNumberValidComponents();
425
426  for (UInt ch=0; ch<numValidComp ; ch++)
427  {
428    const ComponentID compID = ComponentID(ch);
429    const UInt width  = src.getWidth(compID);
430    const UInt height = src.getHeight(compID);
431    const UInt stride = src.getStride(compID);
432    const Pel* blkSrc = src.getAddr(compID);
433    const UInt subBlockWidth=width/numSubBlocksAcross;
434    const UInt subBlockHeight=height/numSubBlocksUp;
435
436    ss << pLinePrefix << " compID: " << compID << "\n";
437    for (UInt y=0; y<height; y++)
438    {
439      if ((y%subBlockHeight)==0 && y!=0)
440      {
441        ss << pLinePrefix << '\n';
442      }
443
444      ss << pLinePrefix;
445      for (UInt x=0; x<width; x++)
446      {
447        if ((x%subBlockWidth)==0 && x!=0)
448        {
449          ss << std::setw(defWidth+2) << "";
450        }
451
452        ss << std::setw(defWidth) << blkSrc[y*stride + x] << ' ';
453      }
454      ss << '\n';
455    }
456    ss << pLinePrefix << " --- \n";
457  }
458}
459
460#ifdef DEBUG_STRING
461Int DebugStringGetPredModeMask(PredMode mode)
462{
463  return (mode==MODE_INTRA)?1:2;
464}
465
466Void DebugInterPredResiReco(std::string &sDebug, TComYuv &pred, TComYuv &resi, TComYuv &reco, Int predmode_mask)
467{
468  if (DebugOptionList::DebugString_Pred.getInt()&predmode_mask)
469  {
470    std::stringstream ss(std::stringstream::out);
471    printBlockToStream(ss, "###inter-pred: ", pred);
472    std::string debugTmp;
473    debugTmp=ss.str();
474    sDebug=debugTmp+sDebug;
475  }
476  if (DebugOptionList::DebugString_Resi.getInt()&predmode_mask)
477  {
478    std::stringstream ss(std::stringstream::out);
479    printBlockToStream(ss, "###inter-resi: ", resi);
480    sDebug+=ss.str();
481  }
482  if (DebugOptionList::DebugString_Reco.getInt()&predmode_mask)
483  {
484    std::stringstream ss(std::stringstream::out);
485    printBlockToStream(ss, "###inter-reco: ", reco);
486    sDebug+=ss.str();
487  }
488}
489#endif
Note: See TracBrowser for help on using the repository browser.