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

Last change on this file since 1353 was 1335, checked in by seregin, 9 years ago

port rev 4413

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