Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 1343)
+++ CMakeLists.txt	(working copy)
@@ -26,6 +26,12 @@
 set( SKIP_SVN_REVISION OFF CACHE BOOL "Don't add SVN path and revision info to the encoder and decoder output" )
 set( SET_ENABLE_TRACING OFF CACHE BOOL "Set ENABLE_TRACING as a compiler flag" )
 set( ENABLE_TRACING OFF CACHE BOOL "If SET_ENABLE_TRACING is on, it will be set to this value" )
+set( SET_ENABLE_METRICS OFF CACHE BOOL "Set ENABLE_METRICS as a compiler flag" )
+set( ENABLE_METRICS OFF CACHE BOOL "If ENABLE_METRICS is on, it will be set to this value" )
+set( SET_METRICS_USE_ITT OFF CACHE BOOL "Set INTEL_NO_ITTNOTIFY_API as a compiler flag" )
+set( ENABLE_METRICS_ITT OFF CACHE BOOL "If ENABLE_METRICS_ITT is on, it will be set to this value" )
+set( ITT_ENABLE_GIT_CLONE OFF CACHE BOOL "If ITT_ENABLE_GIT_CLONE is on and ITT package wasn't found locally 'git clone <ITT ext. repo>' would be used to fetch it" )
+set( ITT_GIT_CLONE_DIR "${CMAKE_CURRENT_BINARY_DIR}/IntelSEAPI" CACHE PATH "If ITT_ENABLE_GIT_CLONE is ON it specifies directory where ITT package would be fetched" )
 
 if( CMAKE_COMPILER_IS_GNUCC )
   set( BUILD_STATIC OFF CACHE BOOL "Build static executables" )
@@ -50,6 +56,9 @@
 # Enable multithreading
 bb_multithreading()
 
+# Enable metrics
+bb_enable_metrics (ENABLE_TRACING ENABLE_METRICS ENABLE_METRICS_ITT ${ITT_ENABLE_GIT_CLONE} ${ITT_GIT_CLONE_DIR})
+
 find_package(OpenMP)
 
 if( OpenMP_FOUND )
Index: cmake/CMakeBuild/cmake/modules/BBuildEnv.cmake
===================================================================
--- cmake/CMakeBuild/cmake/modules/BBuildEnv.cmake	(revision 1343)
+++ cmake/CMakeBuild/cmake/modules/BBuildEnv.cmake	(working copy)
@@ -945,7 +945,6 @@
   endif()
 endfunction()
 
-
 # 
 # Version file parsing utilities
 #
@@ -971,8 +970,11 @@
 #
 include( ${CMAKE_CURRENT_LIST_DIR}/BBuildEnvOpenCV.cmake )
 
-
 #
+# Metrics insrumentation support
+#
+include( ${CMAKE_CURRENT_LIST_DIR}/BBuildEnvMetrics.cmake )
+#
 # Internal macro to setup the build environment. 
 #
 macro( bb_build_env_setup )
Index: cmake/CMakeBuild/cmake/modules/BBuildEnvGit.cmake
===================================================================
--- cmake/CMakeBuild/cmake/modules/BBuildEnvGit.cmake	(revision 1343)
+++ cmake/CMakeBuild/cmake/modules/BBuildEnvGit.cmake	(working copy)
@@ -16,7 +16,7 @@
 
 #]]
 
-if( CMAKE_VERSION VERSION_GREATER_EQUAL 3.10 )
+if( NOT CMAKE_VERSION VERSION_LESS 3.10 )
   include_guard( GLOBAL )
 endif()
 
Index: cmake/CMakeBuild/cmake/modules/BBuildEnvMetrics.cmake
===================================================================
--- cmake/CMakeBuild/cmake/modules/BBuildEnvMetrics.cmake	(nonexistent)
+++ cmake/CMakeBuild/cmake/modules/BBuildEnvMetrics.cmake	(working copy)
@@ -0,0 +1,101 @@
+#[[.rst:
+BBuildEnvMetrics.cmake
+------------
+
+Macros supporting metrics code instrumentation.
+
+Provided Macros
+^^^^^^^^^^^^^^^
+
+::
+
+  bb_enable_metrics()
+
+Macro bb_enable_metrics() 
+
+#]]
+
+include( ${CMAKE_CURRENT_LIST_DIR}/BBuildEnvGit.cmake )
+
+set ( CMAKE_MODULE_PATH
+    ${CMAKE_MODULE_PATH}
+    ${CMAKE_CURRENT_LIST_DIR}
+)
+
+macro( bb_enable_metrics_itt _enable_ITT_CLONE _clone_ITT_DIR)
+
+  find_package(ITT)
+
+  if( NOT TARGET ITT::ITT )
+    if( ${_enable_ITT_CLONE} )
+      bb_git_co_external_dir ( ${_clone_ITT_DIR} master
+        GIT_REPOSITORY "https://github.com/intel/IntelSEAPI.git"
+      )
+    endif()
+
+    if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+      set ( ARCH_64 1 )
+    endif()
+
+    add_subdirectory("${_clone_ITT_DIR}/ittnotify")
+    add_library(ITT::ITT ALIAS ittnotify)
+  endif()
+
+  set_property( TARGET Metrics::Metrics
+    APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "ENABLE_METRICS_ITT=1"
+  )
+
+  set_property( TARGET Metrics::Metrics
+    APPEND PROPERTY INTERFACE_LINK_LIBRARIES ITT::ITT
+  )
+endmacro( bb_enable_metrics_itt )
+
+macro( bb_enable_metrics _enable_TRACING _enable_METRICS _enable_METRICS_ITT _enable_ITT_CLONE _clone_ITT_DIR)
+
+  if( TARGET Metrics::Metrics )
+    message( FATAL_ERROR "bb_enable_metrics(): target Metrics::Metrics already exists. Please contact technical support." )
+  endif()
+
+  add_library( Metrics::Metrics INTERFACE IMPORTED )
+
+  if( SET_METRICS_USE_ITT )
+    if (NOT SET_ENABLE_METRICS )
+      message( SEND_ERROR "${CMAKE_CURRENT_LIST_FILE}: SET_ENABLE_METRICS not set but it is required for ENABLE_METRICS_ITT." ) 
+    endif()
+
+    if( NOT ${_enable_METRICS_ITT} )
+      set_property( TARGET Metrics::Metrics
+        PROPERTY INTERFACE_COMPILE_DEFINITIONS "ENABLE_METRICS_ITT=0"
+      )
+    else()
+      if( NOT ${_enable_METRICS} )
+        message( STATUS "${CMAKE_CURRENT_LIST_FILE}: ENABLE_METRICS_ITT requirtes ENABLE_METRICS, set it to ON." ) 
+        set (${_enable_METRICS} ON)
+      endif()
+
+      bb_enable_metrics_itt(${_enable_ITT_CLONE} ${_clone_ITT_DIR})
+    endif()
+  endif()
+
+  if( SET_ENABLE_METRICS )
+    if (NOT SET_ENABLE_TRACING )
+      message( SEND_ERROR "${CMAKE_CURRENT_LIST_FILE}: SET_ENABLE_TRACING not set but it is required for ENABLE_METRICS." ) 
+    endif()
+
+    if( NOT ${_enable_METRICS} )
+      set_property( TARGET Metrics::Metrics
+        PROPERTY INTERFACE_COMPILE_DEFINITIONS "ENABLE_METRICS=0"
+      )
+    else()
+      if( NOT ${_enable_TRACING} )
+        message( STATUS "${CMAKE_CURRENT_LIST_FILE}: ENABLE_METRICS requirtes ENABLE_TRACING, set it to ON." ) 
+        set (${_enable_TRACING} ON)
+      endif()
+
+      set_property( TARGET Metrics::Metrics
+        APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "ENABLE_METRICS=1"
+      )
+    endif()
+  endif() 
+
+endmacro ( bb_enable_metrics )

Property changes on: cmake/CMakeBuild/cmake/modules/BBuildEnvMetrics.cmake
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: cmake/CMakeBuild/cmake/modules/FindITT.cmake
===================================================================
--- cmake/CMakeBuild/cmake/modules/FindITT.cmake	(nonexistent)
+++ cmake/CMakeBuild/cmake/modules/FindITT.cmake	(working copy)
@@ -0,0 +1,199 @@
+#.rst:
+# FindITT
+# ---------
+#
+# Find Instrumentation and Tracing Technology (ITT) API include dirs and libraries
+#
+# Use this module by invoking find_package with the form
+#
+# ::
+#
+#   find_package(ITT
+#     [REQUIRED]         # Fail with error if ITT is not found
+#   )
+#
+# This module finds headers and libraries
+# For the former case results are reported in variables
+#
+# ::
+#
+#   ITT_FOUND            - True if headers and requested libraries were found
+#   ITT_INCLUDE_DIRS     - ITT include directories
+#   ITT_LIBRARIES        - ITT libraries to be linked
+#
+# This module reads hints about search locations from variables
+#
+# ::
+#
+#   SEAPI_ROOT                 - Preferred installation path for Intel® Single Event API (Intel® SEAPI)
+#                                (https://github.com/intel/IntelSEAPI)
+#   ITT_ROOT/
+#   CMAKE_ITT_HOME             - Preferred installation path for standalone ITT library
+#   INTEL_LIBITTNOTIFY32/
+#   INTEL_LIBITTNOTIFY64       - Preferred ITT library directory
+#   VTUNE_AMPLIFIER_<YEAR>_DIR - VTune Amplifier XE installation path which is set by amplxe-vars.sh/bat script
+#                                See notes about [ITT_NO_VTUNE_PATH] below
+#   CMAKE_VTUNE_HOME           - Explicitly defined VTune Amplifier XE installation path
+#
+# Other variables one may set to control this module are
+#
+# ::
+#
+#   ITT_DEBUG            - Set to ON to enable debug output from FindITT.
+#                          Please enable this before filing any bug report.
+#   ITT_NO_VTUNE_PATH    - Set to ON to not try to find VTUNE_AMPLIFIER_<YEAR>_DIR environment variable
+#
+# Example to find ITT headers and libraries
+#
+# ::
+#
+#   find_package(ITT)
+#   if (ITT_FOUND)
+#     include_directories(${ITT_INCLUDE_DIRS})
+#     add_executable(foo foo.cc)
+#     target_link_libraries(foo ${ITT_LIBRARIES})
+#   endif()
+# 
+# Example to find ITT library and use imported targets::
+#
+# ::
+#
+#   find_package(ITT REQUIRED)
+#   add_executable(foo foo.cc)
+#   target_link_libraries(foo ITT::ITT)
+
+unset (_itt_INC_DIR_HINT)
+unset (_itt_LIB_DIR_HINT)
+
+set (_itt_ARC "")
+if (${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "x86")
+	set (_itt_ARC "64")
+elseif (${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "x64")
+	set (_itt_ARC "64")
+endif()
+
+if ("x${_itt_ARC}" STREQUAL "x")
+	if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set (_itt_ARC "64")
+	else()
+		set (_itt_ARC "32")
+	endif()
+endif()
+
+list (APPEND _itt_INC_DIR_HINT
+	$ENV{ITT_ROOT}
+	$ENV{SEAPI_ROOT}/ittnotify
+	${CMAKE_ITT_HOME}
+	${CMAKE_VTUNE_HOME}
+)
+
+set (_itt_LIBITTNOTIFY $ENV{INTEL_LIBITTNOTIFY${_itt_ARC}})
+if (_itt_LIBITTNOTIFY)
+	get_filename_component (_itt_LIB_DIR_HINT ${_itt_LIBITTNOTIFY} DIRECTORY)
+	get_filename_component (_itt_INC_DIR_HINT ${_itt_LIB_DIR_HINT} DIRECTORY)
+endif()
+
+list (APPEND _itt_INC_DIR_HINT
+	${_itt_INC_DIR_HINT}/ittnotify
+)
+
+if (NOT ITT_NO_VTUNE_PATH)
+	execute_process (COMMAND "${CMAKE_COMMAND}" "-E" "environment"
+		OUTPUT_VARIABLE _itt_ENV_LIST
+	)
+
+	string (REGEX MATCH "VTUNE_AMPLIFIER_[0-9]+_DIR"
+		_itt_VTUNE_DIR ${_itt_ENV_LIST}
+	)
+endif()
+
+if (_itt_VTUNE_DIR)
+	list (APPEND _itt_INC_DIR_HINT $ENV{${_itt_VTUNE_DIR}})
+endif()
+
+if (ITT_DEBUG)
+	message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+					"_itt_INC_DIR_HINT = ${_itt_INC_DIR_HINT}")
+endif()
+
+find_path (ITT_INCLUDE_DIR
+	NAMES ittnotify.h
+		HINTS
+			${_itt_INC_DIR_HINT}
+		PATH_SUFFIXES
+			include
+)
+
+if (ITT_DEBUG)
+	message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+	               "ITT_INCLUDE_DIR = ${ITT_INCLUDE_DIR}")
+endif()
+
+if (ITT_DEBUG)
+	message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+	               "_itt_ARC = ${_itt_ARC}")
+endif()
+
+if (ITT_INCLUDE_DIR)
+	get_filename_component (_itt_INC_DIR_HINT ${ITT_INCLUDE_DIR} DIRECTORY)
+	list (APPEND _itt_LIB_DIR_HINT ${_itt_INC_DIR_HINT})
+endif()
+
+list (APPEND _itt_LIB_DIR_HINT
+	$ENV{ITT_ROOT}
+	$ENV{SEAPI_ROOT}
+)
+
+if (ITT_DEBUG)
+	message (STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+	               "_itt_LIB_DIR_HINT = ${_itt_LIB_DIR_HINT}")
+endif()
+
+find_library (ITT_LIBRARY
+	NAMES
+		libittnotify
+		libittnotify${_itt_ARC}
+		ittnotify
+		ittnotify${_itt_ARC}
+	HINTS
+		${_itt_LIB_DIR_HINT}
+	PATH_SUFFIXES
+		lib${_itt_ARC}
+		lib
+		bin
+)
+
+if (ITT_DEBUG)
+	message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+	               "ITT_LIBRARY = ${ITT_LIBRARY}")
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set MFX_FOUND to TRUE if
+# all listed variables are TRUE
+include (${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS (ITT
+	REQUIRED_VARS ITT_INCLUDE_DIR ITT_LIBRARY
+)
+
+mark_as_advanced(ITT_INCLUDE_DIR ITT_LIBRARY)
+
+if (ITT_FOUND)
+	set (ITT_INCLUDE_DIRS ${ITT_INCLUDE_DIR})
+	set (ITT_LIBRARIES  ${ITT_LIBRARY})
+
+	if (NOT TARGET ITT::ITT)
+		add_library(ITT::ITT UNKNOWN IMPORTED)
+
+		set_target_properties(ITT::ITT PROPERTIES
+			INTERFACE_INCLUDE_DIRECTORIES "${ITT_INCLUDE_DIRS}"
+		)
+
+		set_target_properties(ITT::ITT PROPERTIES
+			IMPORTED_LOCATION "${ITT_LIBRARIES}"
+		)
+
+		set_target_properties(ITT::ITT PROPERTIES
+			INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS}"
+		)
+	endif()
+endif()

Property changes on: cmake/CMakeBuild/cmake/modules/FindITT.cmake
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: source/App/DecoderApp/CMakeLists.txt
===================================================================
--- source/App/DecoderApp/CMakeLists.txt	(revision 1343)
+++ source/App/DecoderApp/CMakeLists.txt	(working copy)
@@ -60,7 +60,7 @@
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities Threads::Threads Metrics::Metrics ${ADDITIONAL_LIBS} )
 
 # Add a SVN revision generator
 # a custom target that is always built
Index: source/App/DecoderApp/DecAppCfg.cpp
===================================================================
--- source/App/DecoderApp/DecAppCfg.cpp	(revision 1343)
+++ source/App/DecoderApp/DecAppCfg.cpp	(working copy)
@@ -41,7 +41,9 @@
 #include "DecAppCfg.h"
 #include "Utilities/program_options_lite.h"
 #include "CommonLib/ChromaFormat.h"
+
 #include "CommonLib/dtrace_next.h"
+#include "CommonLib/dmetrics_next.h"
 
 using namespace std;
 namespace po = df::program_options_lite;
@@ -67,6 +69,10 @@
   string sTracingFile;
   bool   bTracingChannelsList = false;
 #endif
+#if ENABLE_METRICS
+  string sMetricTools;
+  string sMetricsFile;
+#endif
 #if ENABLE_SIMD_OPT
   std::string ignore;
 #endif
@@ -102,8 +108,12 @@
   ("TraceFile",                 sTracingFile,                         string( "" ), "Tracing file" )
 #endif
 #if JEM_COMP
-  ( "AssumeJEM",                m_assumeJEM,                            false, "Assume decoding a JEM bitstream - don't decode the SPSNext-header but set it as it would be set for default JEM configuration" );
+  ( "AssumeJEM",                m_assumeJEM,                            false, "Assume decoding a JEM bitstream - don't decode the SPSNext-header but set it as it would be set for default JEM configuration" )
 #endif
+#if ENABLE_METRICS
+  ("MetricTools",               sMetricTools,                         string( "" ), "Metric tools list (ex: \"ALF\")" )
+  ("MetricFile",                sMetricsFile,                         string( "" ), "Metrics file" )
+#endif
   ;
 
   po::setDefaults(opts);
@@ -140,6 +150,10 @@
   }
 #endif
 
+#if ENABLE_METRICS
+  g_metrics_ctx = metrics_init( sMetricsFile, sMetricTools );
+#endif
+
   // Chroma output bit-depth
   if( m_outputBitDepth[CHANNEL_TYPE_LUMA] != 0 && m_outputBitDepth[CHANNEL_TYPE_CHROMA] == 0 )
   {
@@ -232,6 +246,10 @@
 #if ENABLE_TRACING
   tracing_uninit( g_trace_ctx );
 #endif
+
+#if ENABLE_METRICS
+  metrics_uninit( g_metrics_ctx );
+#endif
 }
 
 //! \}
Index: source/App/EncoderApp/CMakeLists.txt
===================================================================
--- source/App/EncoderApp/CMakeLists.txt	(revision 1343)
+++ source/App/EncoderApp/CMakeLists.txt	(working copy)
@@ -61,7 +61,7 @@
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads Metrics::Metrics ${ADDITIONAL_LIBS} )
 
 # Add a SVN revision generator
 # a custom target that is always built
Index: source/App/EncoderApp/EncAppCfg.cpp
===================================================================
--- source/App/EncoderApp/EncAppCfg.cpp	(revision 1343)
+++ source/App/EncoderApp/EncAppCfg.cpp	(working copy)
@@ -49,6 +49,7 @@
 #include "EncoderLib/RateCtrl.h"
 
 #include "CommonLib/dtrace_next.h"
+#include "CommonLib/dmetrics_next.h"
 
 #define MACRO_TO_STRING_HELPER(val) #val
 #define MACRO_TO_STRING(val) MACRO_TO_STRING_HELPER(val)
@@ -139,6 +140,10 @@
 #if ENABLE_TRACING
   tracing_uninit(g_trace_ctx);
 #endif
+
+#if ENABLE_METRICS
+  metrics_uninit( g_metrics_ctx );
+#endif
 }
 
 Void EncAppCfg::create()
@@ -701,6 +706,11 @@
   string sTracingFile;
   bool   bTracingChannelsList = false;
 #endif
+#if ENABLE_METRICS
+  string sMetricTools;
+  string sMetricsFile;
+#endif
+
 #if ENABLE_SIMD_OPT
   std::string ignore;
 #endif
@@ -1283,6 +1293,11 @@
 #if JEM_COMP
   ("GenerateJEM",                                     m_generateJEM,                            false, "Generate a JEM-compatible bitstream!")
 #endif
+
+#if ENABLE_METRICS
+  ("MetricTools",               sMetricTools,                         string( "" ), "Metric tools list (ex: \"ALF\")" )
+  ("MetricFile",                sMetricsFile,                         string( "" ), "Metrics file" )
+#endif
     ;
 
   for(Int i=1; i<MAX_GOP+1; i++)
@@ -1788,6 +1803,10 @@
   }
 #endif
 
+#if ENABLE_METRICS
+  g_metrics_ctx = metrics_init( sMetricsFile, sMetricTools );
+#endif
+
 #if ENABLE_QPA
   if( m_LargeCTU && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
 #else
Index: source/Lib/CommonLib/CMakeLists.txt
===================================================================
--- source/Lib/CommonLib/CMakeLists.txt	(revision 1343)
+++ source/Lib/CommonLib/CMakeLists.txt	(working copy)
@@ -73,7 +73,7 @@
 endif()
   
 target_include_directories( ${LIB_NAME} PUBLIC . .. ./x86 ../libmd5 )
-target_link_libraries( ${LIB_NAME} Threads::Threads )
+target_link_libraries( ${LIB_NAME} Threads::Threads Metrics::Metrics )
 
 # set needed compile definitions
 set_property( SOURCE ${SSE41_SRC_FILES} APPEND PROPERTY COMPILE_DEFINITIONS USE_SSE41 )
Index: source/Lib/CommonLib/Rom.cpp
===================================================================
--- source/Lib/CommonLib/Rom.cpp	(revision 1343)
+++ source/Lib/CommonLib/Rom.cpp	(working copy)
@@ -55,6 +55,9 @@
 CDTrace *g_trace_ctx = NULL;
 #endif
 
+#if ENABLE_METRICS
+CMetrics *g_metrics_ctx = NULL;
+#endif 
 
 //! \ingroup CommonLib
 //! \{
Index: source/Lib/CommonLib/Rom.h
===================================================================
--- source/Lib/CommonLib/Rom.h	(revision 1343)
+++ source/Lib/CommonLib/Rom.h	(working copy)
@@ -40,7 +40,6 @@
 
 #include "CommonDef.h"
 #include "Common.h"
-
 #include "BinaryDecisionTree.h"
 
 #include <stdio.h>
@@ -279,6 +278,11 @@
 extern CDTrace* g_trace_ctx;
 #endif
 
+#if ENABLE_METRICS
+#include "dmetrics.h"
+extern CMetrics* g_metrics_ctx;
+#endif
+
 const TChar* nalUnitTypeToString(NalUnitType type);
 
 #if HEVC_USE_SCALING_LISTS
Index: source/Lib/CommonLib/TrQuant.cpp
===================================================================
--- source/Lib/CommonLib/TrQuant.cpp	(revision 1343)
+++ source/Lib/CommonLib/TrQuant.cpp	(working copy)
@@ -52,6 +52,7 @@
 
 #include "QuantRDOQ.h"
 
+#include "CommonLib/dmetrics_next.h"
 
 struct coeffGroupRDStats
 {
@@ -661,6 +662,8 @@
 
   if( uiNSSTIdx && !tu.transformSkip[compID] && width >= 4 && height >= 4 && ( width & 3 ) == 0 && ( height & 3 ) == 0 )
   {
+    METRICS_TOOL_USE_UNIT_COND(compID == COMPONENT_Y, g_metrics_ctx, M_NSST, tu);
+
 #if HEVC_USE_MDCS
     const UInt uiScanIdx    = TU::getCoefScanIdx( tu, compID );
 #else
Index: source/Lib/CommonLib/TypeDef.h
===================================================================
--- source/Lib/CommonLib/TypeDef.h	(revision 1343)
+++ source/Lib/CommonLib/TypeDef.h	(working copy)
@@ -103,6 +103,14 @@
 
 #endif // ! ENABLE_TRACING
 
+#ifndef ENABLE_METRICS
+#define ENABLE_METRICS                                    0 // DISABLE by default
+#endif // ! ENABLE_METRICS
+ 
+#ifndef ENABLE_METRICS_ITT
+#define ENABLE_METRICS_ITT                                0 // DISABLE by default
+#endif // ! ENABLE_METRICS_ITT 
+
 #define WCG_EXT                                           0 // part of JEM sharp Luma qp
 
 #if HEVC_TOOLS
Index: source/Lib/CommonLib/dmetrics.cpp
===================================================================
--- source/Lib/CommonLib/dmetrics.cpp	(nonexistent)
+++ source/Lib/CommonLib/dmetrics.cpp	(working copy)
@@ -0,0 +1,175 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2018, ITU/ISO/IEC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \file     dmetrics.cpp
+ *  \brief    Implementation of metrics trace messages support for perfomance estimation
+ */
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <cstdlib>
+
+#include "CommonDef.h"
+
+#include "dmetrics.h"
+#include "dmetrics_next.h"
+
+#if ENABLE_METRICS
+
+#if ENABLE_METRICS_ITT
+metrics_task::metrics_task()
+  : m_domain(nullptr)
+  , m_id(__itt_null)
+{}
+
+metrics_task::metrics_task(__itt_domain* d, char const* name)
+  : m_domain(d)
+{
+  __itt_string_handle* task_name = __itt_string_handle_create(name);
+  m_id = __itt_id_make(m_domain, reinterpret_cast<unsigned long long>(task_name));
+  __itt_task_begin(m_domain, m_id, __itt_null, task_name);
+}
+
+void metrics_task::meta(char const* name, int64_t value)
+{
+  auto meta_name = __itt_string_handle_create(name);
+  __itt_metadata_add(m_domain, m_id, meta_name, __itt_metadata_u64, 1, &value);
+}
+
+metrics_task::metrics_task(metrics_task&& t)
+{
+  m_domain = t.m_domain; t.m_domain = nullptr;
+  m_id = t.m_id; t.m_id = __itt_null;
+}
+
+metrics_task::~metrics_task()
+{ if (m_domain) __itt_task_end(m_domain); }
+#else
+metrics_task::~metrics_task()
+{}
+void metrics_task::meta(char const* name, int64_t)
+{}
+#endif
+
+
+CMetrics::CMetrics( const char *filename, const std::string& sMetricsTools, const std::vector<dmetrics_tool>& tools )
+{
+  FILE* trace_file = fopen( filename, "w" );
+  std::vector<std::string> active = split( sMetricsTools, ',' );
+  std::for_each(std::begin(tools), std::end(tools),
+    [&](dmetrics_tool const& t)
+    {
+       std::unique_ptr<CDTrace> tool{ new CDTrace(trace_file, std::vector<std::string>( {t.name} )) };
+       m_tools.emplace_back(std::make_pair(std::move(tool), t));
+       auto i = std::find(std::begin(active), std::end(active), t.name);
+       if (i != std::end(active))
+         m_tools.back().first->activateChannel(0, true);
+    }
+  );
+
+#if ENABLE_METRICS_ITT
+  m_domain = __itt_domain_create(filename);
+#endif
+}
+
+void CMetrics::activate( int k, const char* channel_name, bool value )
+{
+  auto tool = getTool(k);
+  int channel_number = tool->getChannelNumber(channel_name);
+  if (channel_number < 0)
+      return;
+
+  tool->activateChannel(channel_number, value);
+}
+
+const char* CMetrics::getToolName( int k ) const
+{
+  static const char not_found[] = "";
+
+  return
+    k < m_tools.size() ? m_tools[k].second.name.c_str() : not_found;
+}
+
+int CMetrics::getToolNumber( const char* name ) const
+{
+  auto i = std::find_if(std::begin(m_tools), std::end(m_tools),
+    [&](tool_t const& t) { return name == t.second.name; }
+  );
+
+  return
+    i != std::end(m_tools) ? (*i).second.number : -3;
+}
+
+void CMetrics::getToolsList( std::string& tools ) const
+{
+  std::for_each(std::begin(m_tools), std::end(m_tools),
+    [&](tool_t const& t) { tools += t.second.name + "\n"; }
+  );
+}
+
+#if ENABLE_METRICS_ITT
+metrics_task CMetrics::vtrace( int k, int c, const char* /*format*/, va_list /*args*/ )
+{
+  auto tool = getTool(k);
+  if( !tool->getChannelActive(c) )
+    return metrics_task{};
+
+  const char * channel_name = tool->getChannelName(c);
+  return metrics_task{ m_domain, channel_name };
+}
+#else
+metrics_task CMetrics::vtrace( int k, int c, const char *format, va_list args )
+{
+  auto tool = getTool(k);
+
+  tool->vtrace(c, format, args);
+
+  tool->incrementChannelCounter(c);
+
+  return metrics_task{};
+}
+#endif //ENABLE_METRICS_ITT
+
+metrics_task CMetrics::trace( int k, int c, const char* format, /*va_list args*/... )
+{
+  va_list args;
+  va_start ( args, format );
+  auto t = vtrace(k, c, format, args);
+  va_end ( args );
+
+  return std::move(t);
+}
+
+#endif //ENABLE_METRICS

Property changes on: source/Lib/CommonLib/dmetrics.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: source/Lib/CommonLib/dmetrics.h
===================================================================
--- source/Lib/CommonLib/dmetrics.h	(nonexistent)
+++ source/Lib/CommonLib/dmetrics.h	(working copy)
@@ -0,0 +1,113 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2018, ITU/ISO/IEC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \file     dmetrics.h
+ *  \brief    Implementation of metrics trace messages support for perfomance estimation
+ */
+
+#ifndef _DMETRICS_H_
+#define _DMETRICS_H_
+
+#if ENABLE_METRICS && !ENABLE_TRACING
+  #error "Unexpected configuration error! ENABLE_TRACING should be set to 1 when metrics is enabled"
+#endif
+
+#include <memory>
+#include <map>
+
+#if ENABLE_METRICS_ITT
+#include <ittnotify.h>
+#endif
+
+enum
+{
+    DMETRICS_FLAG_SINGLE = 0,
+    DMETRICS_FLAG_COMPOUND
+};
+
+struct dmetrics_tool
+{
+  int         number;
+  std::string name;
+  int         flags;
+};
+
+struct metrics_task
+{
+#if ENABLE_METRICS_ITT
+  __itt_domain*    m_domain;
+  __itt_id         m_id;
+
+  metrics_task();
+  metrics_task(__itt_domain*, char const* name);
+  metrics_task(metrics_task&&);
+#endif
+
+  ~metrics_task();
+  void meta(char const* name, int64_t);
+};
+
+class CDTrace;
+class CMetrics
+{
+  typedef std::pair<
+    std::unique_ptr<CDTrace>
+    , dmetrics_tool
+  > tool_t;
+
+  std::vector<tool_t> m_tools;
+
+#if ENABLE_METRICS_ITT
+  __itt_domain*               m_domain;
+#endif
+
+public:
+
+  CMetrics( const char *filename, const std::string& sMetricsTools, const std::vector<dmetrics_tool>& tools );
+
+  CDTrace* getTool(int tool) { return tool < m_tools.size() ? m_tools[tool].first.get() : nullptr; }
+  const CDTrace* getTool(int tool) const { return tool < m_tools.size() ? m_tools[tool].first.get() : nullptr; }
+  size_t getCount() const { return m_tools.size(); }
+
+  void activate ( int tool, const char* channel_name, bool value );
+
+  const char* getToolName( int tool ) const;
+  int getToolNumber( const char* name ) const;
+  int getToolFlags( int tool ) const { return tool < m_tools.size() ? m_tools[tool].second.flags : -3; }
+  void getToolsList( std::string& tools ) const;
+
+  metrics_task vtrace( int tool, int channel, const char *format, va_list );
+  metrics_task trace( int tool, int channel, const char *format, /*va_list args*/... );
+};
+
+#endif // _DMETRICS_H_

Property changes on: source/Lib/CommonLib/dmetrics.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: source/Lib/CommonLib/dmetrics_next.h
===================================================================
--- source/Lib/CommonLib/dmetrics_next.h	(nonexistent)
+++ source/Lib/CommonLib/dmetrics_next.h	(working copy)
@@ -0,0 +1,341 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2018, ITU/ISO/IEC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \file     dmetrics_next.h
+ *  \brief    Implementation of metrics trace messages for next software
+ */
+
+#ifndef _DMETRICS_NEXT_H_
+#define _DMETRICS_NEXT_H_
+
+#include "dmetrics.h"
+#include "dtrace_next.h"
+
+#include "CommonLib/Unit.h"
+#include "CommonLib/Slice.h"
+#include "CommonLib/Picture.h"
+
+#if ENABLE_METRICS
+
+enum DMETRICS_TOOL
+{
+  M_FRAME,
+  M_AFFINE,
+  M_NSST,
+  M_EMT,
+};
+
+inline int metricsToolChannel( CMetrics *ctx, int k, const char* channel_name)
+{
+  auto tool = ctx->getTool(k);
+  if (!tool)
+      return -1;
+
+  int const flags = ctx->getToolFlags(k);
+  int channel = tool->getChannelNumber( channel_name );
+  if (channel < 0)
+  {
+    if (!(flags & DMETRICS_FLAG_COMPOUND))
+      return -1;
+
+    bool activate = tool->getChannelActive(0);
+    tool->addChannel(channel_name, activate);
+    channel = tool->getChannelNumber( channel_name );
+  }
+
+  return channel;
+}
+
+inline metrics_task metricsTool( CMetrics *ctx, int k, const char* channel_name, const char *format, /*va_list args*/... )
+{
+  auto tool = ctx->getTool(k);
+  if (!tool)
+    return metrics_task{};
+
+  int const channel = metricsToolChannel(ctx, k, channel_name);
+  if (channel < 0)
+    return metrics_task{};
+
+  va_list args;
+  va_start ( args, format );
+  auto t = ctx->vtrace( k, channel, format, args);
+  va_end ( args );
+
+  return std::move(t);
+}
+
+inline metrics_task metricsTool( CMetrics *ctx, int k, const char* channel_name, int indent, int fill)
+{
+  auto tool = ctx->getTool(k);
+  if (!tool)
+      return metrics_task{};
+
+  int const channel = metricsToolChannel(ctx, k, channel_name);
+  if (channel < 0)
+    return metrics_task{};
+
+  auto t = metricsTool(ctx, k, channel_name, "%*s%-*s:%8lld\n",
+    indent,
+    "",
+    fill,
+    channel_name,
+    DTRACE_GET_COUNTER( tool, channel )
+  );
+
+  return std::move(t);
+}
+
+inline metrics_task metricsToolUse( CMetrics *ctx, int k, const char* channel_name )
+{
+  auto tool = ctx->getTool(k);
+  if (!tool)
+      return metrics_task{};
+
+  int const flags = ctx->getToolFlags(k);
+  if (flags & DMETRICS_FLAG_COMPOUND)
+  {
+    DTRACE_INCR_COUNTER( tool, 0 );
+#if ENABLE_METRICS_ITT
+    metricsTool( ctx, k, ctx->getToolName(k), 0, 0 );
+#endif
+  }
+
+  int const channel = metricsToolChannel(ctx, k, channel_name);
+  if (channel < 0)
+    return metrics_task{};
+
+  DTRACE_INCR_COUNTER( tool, channel );
+
+#if ENABLE_METRICS_ITT
+  return metricsTool( ctx, k, channel_name, 0, 0 );
+#else
+  return metrics_task{};
+#endif
+}
+
+inline metrics_task metricsToolUse( CMetrics *ctx, int k )
+{
+  return metricsToolUse(ctx, k, ctx->getToolName(0));
+}
+
+inline int64_t metricsToolFinalizeChannel( CMetrics *ctx, SPS const* sps, int k, const char* channel_name, int indent, int fill)
+{
+  auto tool = ctx->getTool(k);
+  if (!tool)
+      return 0;
+
+  int const channel = metricsToolChannel(ctx, k, channel_name);
+  if (channel < 0)
+    return 0;
+
+  int64_t const counter = DTRACE_GET_COUNTER( tool, channel );
+  int64_t const pixels  = DTRACE_GET_VALUE( tool, channel );
+  if (!pixels)
+    metricsTool(ctx, k, channel_name, indent, fill);
+  else
+    metricsTool(ctx, k, channel_name, "%*s%-*s:%8lld pixels:%8lld\n",
+      indent,
+      "",
+      fill,
+      channel_name,
+      counter,
+      pixels
+    );
+
+  return pixels;
+}
+
+inline void metricsToolFinalize(CMetrics *ctx, SPS const* sps)
+{
+#if !ENABLE_METRICS_ITT
+  for (int i = 0; i < int(ctx->getCount()); ++i)
+  {
+    auto tool = ctx->getTool(i);
+    std::string list;
+    tool->getChannelsList(list);
+    std::vector<std::string> channels = split( list, '\n' ); 
+
+    auto begin = std::begin(channels);
+    int indent = 0;
+    int const flags = ctx->getToolFlags(i);
+    if (flags & DMETRICS_FLAG_COMPOUND)
+    {
+      metricsToolFinalizeChannel( ctx, sps, i, (*begin).c_str(), 0, 0 );
+      indent = 4;
+      ++begin;
+    }
+
+    size_t max = 0;
+    std::for_each(begin, std::end(channels),
+      [&max](std::string const& name)
+      { size_t const l = name.length(); if (l > max) max = l; }
+    );
+
+    int64_t impacted_pixels = 0;
+    std::for_each(begin, std::end(channels),
+      [&](std::string const& name) { impacted_pixels += metricsToolFinalizeChannel( ctx, sps, i, name.c_str(), indent, int(max) ); }
+    );
+
+    if (flags & DMETRICS_FLAG_COMPOUND)
+    {
+      char const* n1 = "Total impacted pixels";
+      char const* n2 = "% impacted pixels";
+      DTRACE(tool, 0, "%*s %s\n", indent, n1, n2);
+
+      int64_t const total_pixels = DTRACE_GET_VALUE(ctx->getTool(M_FRAME), 0);
+      double const impacted_percent =
+        double(impacted_pixels) / total_pixels * 100.;
+
+      DTRACE(tool, 0, "%*lld %*.2f%%\n",
+        strlen(n1),
+        impacted_pixels,
+        strlen(n2) - 1, //minus % sign
+        impacted_percent
+      );
+    }
+
+    DTRACE_WITHOUT_COUNT(tool, 0, "\n");
+  }
+#endif
+}
+
+inline metrics_task metricsToolUseUnit( CMetrics *ctx, int k, const char* channel_name, UInt width, UInt height )
+{
+  auto t = metricsToolUse(ctx, k, channel_name);
+
+  auto tool = ctx->getTool(k);
+  int const channel = metricsToolChannel(ctx, k, channel_name);
+  if (channel < 0)
+    return metrics_task{};
+
+  int64_t const counter = DTRACE_GET_COUNTER( tool, channel );
+  int64_t const pixels = counter * width * height;
+  DTRACE_SET_VALUE(tool, channel, pixels);
+
+  t.meta("pixels", pixels);
+
+  return std::move(t);
+}
+
+inline metrics_task metricsToolUseUnit( CMetrics *ctx, int k, UInt width, UInt height )
+{
+  std::stringstream name(ctx->getToolName(k), std::ios_base::out | std::ios_base::ate);
+  name << "_" << width << "x" << height;
+  return metricsToolUseUnit(ctx, k, name.str().c_str(), width, height);
+}
+
+inline metrics_task metricsToolUseUnit( CMetrics *ctx, int k, const char* channel_name, UnitArea const& unit )
+{
+  return metricsToolUseUnit(ctx, k, channel_name, unit.Y().width, unit.Y().height);
+}
+
+inline metrics_task metricsToolUseUnit( CMetrics *ctx, int k, UnitArea const& unit )
+{
+  return metricsToolUseUnit(ctx, k, unit.Y().width, unit.Y().height);
+}
+
+inline metrics_task metricsToolUsePicture( CMetrics *ctx, int k, Picture const* picture )
+{
+  return metricsToolUseUnit(ctx, k, ctx->getTool(k)->getChannelName(0), *picture);
+}
+
+#define METRICS_TOOL_TO_STRING(x) METRICS_TOOL_TO_STRING_IMPL(x)
+#define METRICS_TOOL_TO_STRING_IMPL(x) #x
+
+#define METRICS_TOOL_CAT_IMPL(a, b) a ## b
+#define METRICS_TOOL_CAT(x, y) METRICS_TOOL_CAT_IMPL(x, y)
+
+#if defined(_MSC_VER)
+#define METRICS_TOOL_MAKE_UNIQUE(name) METRICS_TOOL_CAT(name, __COUNTER__)
+#else
+#define METRICS_TOOL_MAKE_UNIQUE(name) METRICS_TOOL_CAT(name, __LINE__)
+#endif
+
+#define METRICS_TOOL(ctx, tool, channel, ...)            auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_t)  = metricsTool( ctx, tool, channel, __VA_ARGS__ )
+#define METRICS_TOOL_USE(ctx, tool, ...)                 auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_u)  = metricsToolUse( ctx, tool, __VA_ARGS__ )
+#define METRICS_TOOL_USE_COND(cond, ctx, tool, ...)      auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_uc) = cond ? metricsToolUse( ctx, tool, __VA_ARGS__ ) : metrics_task{};
+#define METRICS_TOOL_FINIT(ctx, ...)                     metricsToolFinalize( ctx, __VA_ARGS__ )
+
+#define METRICS_TOOL_USE_UNIT(ctx, tool, ...)            auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_uu)  = metricsToolUseUnit( ctx, tool, __VA_ARGS__ )
+#define METRICS_TOOL_USE_UNIT_COND(cond, ctx, tool, ...) auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_uuc) = cond ? metricsToolUseUnit( ctx, tool, __VA_ARGS__ ) : metrics_task{};
+#define METRICS_TOOL_USE_PICTURE(ctx, tool, picture)     auto METRICS_TOOL_MAKE_UNIQUE(metrics_task_up)  = metricsToolUsePicture( ctx, tool, picture )
+
+#define _TOOL_DEF(_s, _f) { _s, (std::string(#_s)), _f }
+
+inline CMetrics* metrics_init( std::string& sMetricsFile, std::string& sMetricsTools )
+{
+  dmetrics_tool next_tools[] =
+  {
+    _TOOL_DEF( M_FRAME,  DMETRICS_FLAG_SINGLE ),
+    _TOOL_DEF( M_AFFINE, DMETRICS_FLAG_COMPOUND ),
+    _TOOL_DEF( M_NSST,   DMETRICS_FLAG_COMPOUND ),
+    _TOOL_DEF( M_EMT,    DMETRICS_FLAG_COMPOUND ),
+  };
+
+  std::vector<dmetrics_tool> tools( next_tools, &next_tools[sizeof( next_tools ) / sizeof( next_tools[0] )] );
+
+  if( !sMetricsFile.empty() || !sMetricsFile.empty() )
+  {
+    msg( VERBOSE, "\n" );
+    msg( VERBOSE, "Metrics is enabled: %s : %s\n", sMetricsFile.c_str(), sMetricsTools.c_str() );
+  }
+ 
+  CMetrics *pMetrics = new CMetrics( sMetricsFile.c_str(), sMetricsTools, tools );
+  //alway activate M_FRAME since it is used for calculation
+  pMetrics->getTool(M_FRAME)->activateChannel(0, true);
+
+  return pMetrics;
+}
+
+inline void metrics_uninit( CMetrics *pMetrics )
+{
+  if( pMetrics )
+  {
+    delete pMetrics;
+  }
+}
+#else
+
+#define METRICS_TOOL(...)
+#define METRICS_TOOL_USE(...)
+#define METRICS_TOOL_USE_COND(...)
+#define METRICS_TOOL_FINIT(...)
+
+#define METRICS_TOOL_USE_PICTURE(...)
+#define METRICS_TOOL_USE_UNIT(...)
+#define METRICS_TOOL_USE_UNIT_COND(...)
+
+#endif //ENABLE_METRICS
+
+
+#endif // _DMETRICS_NEXT_H_

Property changes on: source/Lib/CommonLib/dmetrics_next.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: source/Lib/CommonLib/dtrace.cpp
===================================================================
--- source/Lib/CommonLib/dtrace.cpp	(revision 1343)
+++ source/Lib/CommonLib/dtrace.cpp	(working copy)
@@ -84,36 +84,18 @@
     rule_list.push_back( rule );
 }
 
-static inline
-std::vector<std::string> &split( const std::string &s, char delim, std::vector<std::string> &elems )
+CDTrace::CDTrace( FILE* trace_file, vstring channel_names )
+  : copy(true), m_trace_file(trace_file), m_error_code( 0 )
 {
-    std::stringstream ss( s );
-    std::string item;
-    while ( std::getline( ss, item, delim ) ) {
-        elems.push_back( item );
-    }
-    return elems;
+  int i = 0;
+  for( vstring::iterator ci = channel_names.begin(); ci != channel_names.end(); ++ci ) {
+      deserializationTable[*ci] = i++;
+      chanRules.push_back( Channel() );
+  }
 }
-
-static inline
-std::vector<std::string> split( const std::string &s, char delim )
-{
-    std::vector<std::string> elems;
-    split( s, delim, elems );
-    return elems;
-}
-
 CDTrace::CDTrace( const char *filename, vstring channel_names )
-    : copy(false), m_trace_file(NULL), m_error_code( 0 )
+    : CDTrace(filename ? fopen( filename, "w" ) : NULL, channel_names)
 {
-    if( filename )
-        m_trace_file = fopen( filename, "w" );
-
-    int i = 0;
-    for( vstring::iterator ci = channel_names.begin(); ci != channel_names.end(); ++ci ) {
-        deserializationTable[*ci] = i++;
-        chanRules.push_back( Channel() );
-    }
 }
 
 CDTrace::CDTrace( const char *filename, const dtrace_channels_t& channels )
@@ -181,7 +163,7 @@
 bool _cf_le ( int bound, int val ) { return ( val<=bound ); }
 bool _cf_ge ( int bound, int val ) { return ( val>=bound ); }
 
-int CDTrace::addRule( std::string rulestring )
+int CDTrace::addRule( const std::string& rulestring )
 {
     vstring chans_conds = split( rulestring, ':' );
     vstring channels = split( chans_conds[0], ',' );
@@ -231,6 +213,15 @@
     return 0;
 }
 
+int  CDTrace::addChannel( const std::string& channel_name, bool active )
+{
+  deserializationTable[channel_name] = int(chanRules.size());
+  chanRules.push_back( Channel() );
+  chanRules.back().activate(active);
+
+  return 0;
+}
+
 bool CDTrace::update( state_type stateval )
 {
     state[stateval.first] = stateval.second;
@@ -255,6 +246,16 @@
   }
 }
 
+bool CDTrace::getChannelActive( int channel_number ) const
+{
+  return chanRules[channel_number].active();
+}
+
+void CDTrace::activateChannel ( int channel_number, bool value )
+{
+  chanRules[channel_number].activate(value);
+}
+
 const char* CDTrace::getChannelName( int channel_number )
 {
   static const char not_found[] = "";
@@ -267,6 +268,14 @@
   return not_found;
 }
 
+
+int CDTrace::getChannelNumber( const char* channel_name )
+{
+  channel_map_t::const_iterator i = deserializationTable.find(channel_name);
+  return
+    i != deserializationTable.end() ? i->second : -3;
+}
+
 std::string CDTrace::getErrMessage()
 {
   std::string str = "";
@@ -285,6 +294,15 @@
   return str;
 }
 
+void CDTrace::vtrace( int k, const char *format, va_list args )
+{
+  if( m_trace_file && chanRules[k].active() )
+  {
+    vfprintf ( m_trace_file, format, args );
+    fflush( m_trace_file );
+  }
+}
+
 template< bool bCount>
 void CDTrace::dtrace( int k, const char *format, /*va_list args*/... )
 {
@@ -298,7 +316,6 @@
     if( bCount )
       chanRules[k].incrementCounter();
   }
-  return;
 }
 
 template void CDTrace::dtrace<true>( int k, const char *format, /*va_list args*/... );
@@ -319,4 +336,4 @@
     va_end( args );
   }
   return;
-}
+}
\ No newline at end of file
Index: source/Lib/CommonLib/dtrace.h
===================================================================
--- source/Lib/CommonLib/dtrace.h	(revision 1343)
+++ source/Lib/CommonLib/dtrace.h	(working copy)
@@ -75,17 +75,21 @@
 {
     typedef std::vector<Condition> Rule;
 public:
-    Channel() : rule_list(), _active(false), _counter(0) {}
+    Channel() : rule_list(), _active(false), _counter(0), _value(0) {}
     void update( std::map< CType, int > state );
-    bool active() { return _active; }
+    bool active() const { return _active; }
+    void activate(bool value) { _active = value; }
     void add( Rule rule );
     void incrementCounter() { _counter++; }
     void decrementCounter() { _counter--  ; }
     int64_t getCounter() { return _counter; }
+    int64_t getValue() { return _value; }
+    void setValue(int64_t value) { _value = value; }
 private:
     std::list< Rule > rule_list;
     bool _active;
     int64_t _counter;
+    int64_t _value;
 };
 
 class CDTrace
@@ -92,7 +96,7 @@
 {
   typedef std::pair< CType, int > state_type;
   //friend class Rules;
-private:
+protected:
     bool          copy;
     FILE         *m_trace_file;
     int           m_error_code;
@@ -107,27 +111,53 @@
 
 public:
     CDTrace() : copy(false), m_trace_file(NULL) {}
+    CDTrace( FILE* trace_file, vstring channel_names );
     CDTrace( const char *filename, vstring channel_names );
     CDTrace( const char *filename, const dtrace_channels_t& channels );
     CDTrace( const std::string& sTracingFile, const std::string& sTracingRule, const dtrace_channels_t& channels );
     CDTrace( const CDTrace& other );
     CDTrace& operator=( const CDTrace& other );
-    ~CDTrace();
+    virtual ~CDTrace();
     void swap         ( CDTrace& other );
-    int  addRule      ( std::string rulestring );
+    int  addRule      ( const std::string& rulestring );
+    int  addChannel   ( const std::string& channel_name, bool active );
+    void vtrace       ( int, const char *format, va_list );
     template<bool bCount>
     void dtrace       ( int, const char *format, /*va_list args*/... );
     void dtrace_repeat( int, int i_times, const char *format, /*va_list args*/... );
     bool update       ( state_type stateval );
-    int  init( vstring channel_names );
     int  getLastError() { return m_error_code;  }
+    bool getChannelActive( int channel_number ) const;
+    void activateChannel ( int channel_number, bool value );
     const char*  getChannelName( int channel_number );
+    int  getChannelNumber( const char* channel_name );
     void getChannelsList( std::string& sChannels );
     std::string getErrMessage();
     int64_t getChannelCounter( int channel ) { return chanRules[channel].getCounter(); }
     void    decrementChannelCounter( int channel ) { chanRules[channel].decrementCounter(); }
+    void    incrementChannelCounter( int channel ) { chanRules[channel].incrementCounter(); }
+
+    int64_t getChannelValue( int channel ) { return chanRules[channel].getValue(); }
+    void    setChannelValue( int channel, int64_t value ) { chanRules[channel].setValue(value); }
 };
 
+static inline
+std::vector<std::string> &split( const std::string &s, char delim, std::vector<std::string> &elems )
+{
+    std::stringstream ss( s );
+    std::string item;
+    while ( std::getline( ss, item, delim ) ) {
+        elems.push_back( item );
+    }
+    return elems;
+}
 
+static inline
+std::vector<std::string> split( const std::string &s, char delim )
+{
+    std::vector<std::string> elems;
+    split( s, delim, elems );
+    return elems;
+}
+
 #endif // _DTRACE_H_
-
Index: source/Lib/CommonLib/dtrace_next.h
===================================================================
--- source/Lib/CommonLib/dtrace_next.h	(revision 1343)
+++ source/Lib/CommonLib/dtrace_next.h	(working copy)
@@ -153,7 +153,6 @@
     delete pDtrace;
 }
 
-
 template< typename Tsrc >
 void dtrace_block( CDTrace *trace_ctx, DTRACE_CHANNEL channel, Tsrc *buf, unsigned stride, unsigned block_w, unsigned block_h )
 {
@@ -192,6 +191,7 @@
 #define DTRACE(ctx,channel,...)              ctx->dtrace<true>( channel, __VA_ARGS__ )
 #define DTRACE_WITHOUT_COUNT(ctx,channel,...) ctx->dtrace<false>( channel, __VA_ARGS__ )
 #define DTRACE_DECR_COUNTER(ctx,channel)     ctx->decrementChannelCounter( channel )
+#define DTRACE_INCR_COUNTER(ctx,channel)     ctx->incrementChannelCounter( channel )
 #define DTRACE_UPDATE(ctx,s)                 if((ctx)){(ctx)->update((s));}
 #define DTRACE_REPEAT(ctx,channel,times,...) ctx->dtrace_repeat( channel, times,__VA_ARGS__ )
 #define DTRACE_COND(cond,ctx,channel,...)    { if( cond ) ctx->dtrace<true>( channel, __VA_ARGS__ ); }
@@ -198,6 +198,8 @@
 #define DTRACE_BLOCK(...)                    dtrace_block(__VA_ARGS__)
 #define DTRACE_FRAME_BLOCKWISE(...)          dtrace_frame_blockwise(__VA_ARGS__)
 #define DTRACE_GET_COUNTER(ctx,channel)      ctx->getChannelCounter(channel)
+#define DTRACE_GET_VALUE(ctx,channel)        ctx->getChannelValue(channel)
+#define DTRACE_SET_VALUE(ctx,channel,val)    ctx->setChannelValue(channel, val)
 
 #include "CommonLib/Rom.h"
 
@@ -272,7 +274,10 @@
 #define DTRACE_BLOCK(...)
 #define DTRACE_FRAME_BLOCKWISE(...)
 #define DTRACE_GET_COUNTER(ctx,channel)
+#define DTRACE_GET_VALUE(ctx,channel)
+#define DTRACE_SET_VALUE(ctx,channel,val)
 
+
 #endif
 
 
Index: source/Lib/DecoderLib/CMakeLists.txt
===================================================================
--- source/Lib/DecoderLib/CMakeLists.txt	(revision 1343)
+++ source/Lib/DecoderLib/CMakeLists.txt	(working copy)
@@ -45,7 +45,7 @@
 endif()
 
 target_include_directories( ${LIB_NAME} PUBLIC . )
-target_link_libraries( ${LIB_NAME} CommonLib Threads::Threads )
+target_link_libraries( ${LIB_NAME} CommonLib Threads::Threads Metrics::Metrics )
 
 # example: place header files in different folders
 source_group( "Natvis Files" FILES ${NATVIS_FILES} )
Index: source/Lib/DecoderLib/DecCu.cpp
===================================================================
--- source/Lib/DecoderLib/DecCu.cpp	(revision 1343)
+++ source/Lib/DecoderLib/DecCu.cpp	(working copy)
@@ -44,8 +44,8 @@
 #include "CommonLib/UnitTools.h"
 
 #include "CommonLib/dtrace_buffer.h"
+#include "CommonLib/dmetrics_next.h"
 
-
 //! \ingroup DecoderLib
 //! \{
 
@@ -439,6 +439,8 @@
 {
   for( auto &pu : CU::traversePUs( cu ) )
   {
+    METRICS_TOOL_USE_UNIT_COND(pu.cu->affine, g_metrics_ctx, M_AFFINE, pu);
+
     MergeCtx mrgCtx;
 
     if( pu.mergeFlag )
Index: source/Lib/DecoderLib/DecLib.cpp
===================================================================
--- source/Lib/DecoderLib/DecLib.cpp	(revision 1343)
+++ source/Lib/DecoderLib/DecLib.cpp	(working copy)
@@ -40,6 +40,8 @@
 
 #include "CommonLib/dtrace_next.h"
 #include "CommonLib/dtrace_buffer.h"
+#include "CommonLib/dmetrics_next.h"
+
 #include "CommonLib/Buffer.h"
 #include "CommonLib/UnitTools.h"
 
@@ -379,6 +381,8 @@
 
 Void DecLib::destroy()
 {
+  METRICS_TOOL_FINIT( g_metrics_ctx, m_parameterSetManager.getActiveSPS() );
+
   delete m_apcSlicePilot;
   m_apcSlicePilot = NULL;
 
@@ -535,6 +539,8 @@
 
 Void DecLib::finishPicture(Int& poc, PicList*& rpcListPic, MsgLevel msgl )
 {
+  METRICS_TOOL_USE_PICTURE(g_metrics_ctx, M_FRAME, m_pcPic);
+
   Slice*  pcSlice = m_pcPic->cs->slice;
 #if JEM_TOOLS
   if( m_pcPic->cs->sps->getSpsNext().getALFEnabled() )