source: 3DVCSoftware/branches/HTM-16.2-dev/source/Lib/TLibCommon/Debug.cpp @ 1412

Last change on this file since 1412 was 1412, checked in by tech, 7 years ago
  • Update HM-16.18
  • Cleanups
  • Encoder Extension

-- Representation formats
-- Parameter set sharing
-- GOP configuration

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