1 /* -----------------------------------------------------------------------------
2 The copyright in this software is being made available under the BSD
3 License, included below. No patent rights, trademark rights and/or
4 other Intellectual Property Rights other than the copyrights concerning
5 the Software are granted under this license.
6 
7 For any license concerning other Intellectual Property rights than the software,
8 especially patent licenses, a separate Agreement needs to be closed.
9 For more information please contact:
10 
11 Fraunhofer Heinrich Hertz Institute
12 Einsteinufer 37
13 10587 Berlin, Germany
14 www.hhi.fraunhofer.de/vvc
15 vvc@hhi.fraunhofer.de
16 
17 Copyright (c) 2018-2021, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
18 All rights reserved.
19 
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions are met:
22 
23  * Redistributions of source code must retain the above copyright notice,
24    this list of conditions and the following disclaimer.
25  * Redistributions in binary form must reproduce the above copyright notice,
26    this list of conditions and the following disclaimer in the documentation
27    and/or other materials provided with the distribution.
28  * Neither the name of Fraunhofer nor the names of its contributors may
29    be used to endorse or promote products derived from this software without
30    specific prior written permission.
31 
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
36 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
42 THE POSSIBILITY OF SUCH DAMAGE.
43 
44 
45 ------------------------------------------------------------------------------------------- */
46 
47 /** \file     dtrace_next.h
48  *  \brief    DTrace support for next software
49  */
50 
51 #pragma once
52 
53 #include "dtrace.h"
54 
55 #include "CommonLib/CommonDef.h"
56 #include "CommonLib/Rom.h"
57 
58 #include <cmath>
59 
60 namespace vvdec
61 {
62 
63 #if ENABLE_TRACING
64 
65 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 //
67 // DTRACE SHORT MANUAL
68 //
69 // 1. General info
70 //
71 // DTrace is a simple tracer that can be controlled at command line of the executable.
72 //
73 // Please have a look into command line parameter options to find the correspondent DTrace parameters.
74 // There are only two command-line parameters: tracing file and tracing rule.
75 // At initialization, DTrace-module parses the rule and set up the tracing context.
76 // The tracing context is stored in a global variable. All trace-outputs should use this global context.
77 //
78 // 2. Parameters
79 // 2.1 Tracing file (--TraceFile)
80 //
81 // Just a filename for a text-file.
82 // E.g.: --TraceFile="tracefile_rec.txt"
83 //
84 // 2.2 Tracing rule (--TraceRule)
85 //
86 // Tracing rule describes when during a runtime a particular output should be activated.
87 // Tracing rule consists of tracing channel(s) and tracing condition(s).
88 // The construction of the rule is: "channel_1,channel_2,...:condition_1,condition_2,..."
89 //
90 // Example for a tracing rule: --TraceRule="D_CABAC:poc==0"
91 // Here, tracing channel is D_CABAC and condition is poc==0, which means CABAC tracing output is activated at POC 0 only.
92 // You can also use poc>=2 or set the range like poc>=0,poc<=3 for example.
93 //
94 //
95 // 2.2.1 Tracing channel
96 //
97 // Channels are defined in dtrace_next.h. Users can add their own channels.
98 // Just put the channel definition into enum-list AND add it to the next_channels-table in the function tracing_init().
99 //
100 // 2.2.2 Tracing condition
101 //
102 // Currently supported: poc (the currently processed poc) and final ('0' if currently in RD-search, '1' if the current state is final)
103 // NOTE: Conditions are added and updated during runtime through DTRACE_UPDATE(...).
104 // It updates the DTrace internal state, so channels can be activated at the right moment.
105 // If it's not updated properly (at right place in the code, e.g. too late), the trace output can become wrong.
106 // For example, "poc"-condition should be updated at the start of the picture(AccesUnit).
107 // Please look into source code for how the "poc"-condition is used.
108 //
109 // 3. Using of DTrace macros
110 //
111 // The most used macro is DTRACE. It's like a printf-function with some additional parameters at the beginning.
112 // Format:
113 // DTRACE( tracing context, tracing channel, "..." [,params] );
114 // Example:
115 // DTRACE( g_trace_ctx, D_CABAC, "EP=%d \n", bin );
116 // There are also macros for output of buffers, picture components or conditional-outputs available. Please have a look into dtrace_next.h.
117 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 
119 
120 // DTrace channels
121 // Use already defined channels or add your own tracing channels
122 
123 enum DTRACE_CHANNEL
124 {
125   D_COMMON,
126   D_HEADER,               // header file infos
127   D_NALUNITHEADER,        // NAL unit header infos
128   D_RPSINFO,              // bits used to send the RPS
129   D_REC_CB_LUMA,          // reconstructed coding block luma pixel
130   D_REC_CB_CHROMA,        // reconstructed coding block chroma pixel
131   D_REC_CB_LUMA_LF,       // reconstructed coding block luma pixel after deblocking filter
132   D_REC_CB_CHROMA_LF,     // reconstructed coding block chroma pixel after deblocking filter
133   D_REC_CB_LUMA_SAO,      // reconstructed coding block luma pixel after SAO filter
134   D_REC_CB_CHROMA_SAO,    // reconstructed coding block chroma pixel after SAO filter
135   D_REC_CB_LUMA_ALF,      // reconstructed coding block luma pixel after ALF filter
136   D_REC_CB_CHROMA_ALF,    // reconstructed coding block chroma pixel after ALF filter
137   D_ME,                   // Motion Estimation
138   D_CABAC,                // CABAC engine
139   D_SYNTAX,               // syntax
140   D_SYNTAX_RESI,          // syntax of the residual coding
141   D_BEST_MODE,            // Cost for coding mode (encoder only)
142   D_MODE_COST,            // Cost for coding mode (encoder only)
143   D_QP_PRED,              // QP Prediction for DQP process
144   D_DQP,                  // Delta QP read/write
145   D_QP,                   // final CU QP at reading/writing stage
146   D_QP_PER_CTU,           // final QP per CTU at reading
147   D_MISC,                 // Miscellaneous
148   D_DECISIONTREE,         // decision tree tracing
149   D_TU_ABS_SUM,
150   D_EST_FRAC_BITS,
151   D_INTRA_COST,           //intra cost
152   D_PRED,
153   D_RESIDUALS,
154   D_TCOEFF,
155   D_RDOQ,
156   D_RDOQ_MORE,
157   D_RDOQ_COST,
158   D_TMP,
159   D_CRC,
160   D_CRC_LF
161 };
162 #define _CNL_DEF(_s) {_s,(std::string(#_s))}
163 
tracing_uninit(CDTrace * pDtrace)164 inline void tracing_uninit( CDTrace *pDtrace )
165 {
166   if( pDtrace )
167     delete pDtrace;
168 }
169 
170 
171 template< typename Tsrc >
dtrace_block(CDTrace * trace_ctx,DTRACE_CHANNEL channel,Tsrc * buf,ptrdiff_t stride,unsigned block_w,unsigned block_h)172 void dtrace_block( CDTrace *trace_ctx, DTRACE_CHANNEL channel, Tsrc *buf, ptrdiff_t stride, unsigned block_w, unsigned block_h )
173 {
174   unsigned i, j;
175   for( j = 0; j < block_h; j++ )
176   {
177     for( i = 0; i < block_w; i++ )
178     {
179       trace_ctx->dtrace<false>( channel, "%04x ", buf[j*stride + i] );
180       //trace_ctx->dtrace<false>( channel, "%4d ", buf[j*stride + i] );
181     }
182     trace_ctx->dtrace<false>( channel, "\n" );
183   }
184   trace_ctx->dtrace<false>( channel, "\n" );
185 }
186 
187 template< typename Tsrc >
dtrace_frame_blockwise(CDTrace * trace_ctx,DTRACE_CHANNEL channel,Tsrc * buf,ptrdiff_t stride,unsigned frm_w,unsigned frm_h,unsigned block_w,unsigned block_h)188 void dtrace_frame_blockwise( CDTrace *trace_ctx, DTRACE_CHANNEL channel, Tsrc *buf, ptrdiff_t stride, unsigned frm_w, unsigned frm_h, unsigned block_w, unsigned block_h )
189 {
190   unsigned i, j, block;
191   for( j = 0, block = 0; j < frm_h; j += block_h )
192   {
193     unsigned blockhf = std::min( block_h, frm_h - j);
194     Tsrc *p_buf = buf + j*stride;
195     for( i = 0; i < frm_w; i += block_w, block++ )
196     {
197       unsigned blockwf = std::min( block_w, frm_w - i);
198 
199       trace_ctx->dtrace<false>( channel, "Frame BLOCK=%d (x,y) = (%d, %d)\n", block, i, j );
200       dtrace_block( trace_ctx, channel, p_buf, stride, blockwf, blockhf );
201       p_buf += block_w;
202     }
203   }
204 }
205 
206 #define DTRACE(ctx,channel,...)              ctx->dtrace<true>( channel, __VA_ARGS__ )
207 #define DTRACE_WITHOUT_COUNT(ctx,channel,...) ctx->dtrace<false>( channel, __VA_ARGS__ )
208 #define DTRACE_DECR_COUNTER(ctx,channel)     ctx->decrementChannelCounter( channel )
209 #define DTRACE_UPDATE(ctx,s)                 if((ctx)){(ctx)->update((s));}
210 #define DTRACE_REPEAT(ctx,channel,times,...) ctx->dtrace_repeat( channel, times,__VA_ARGS__ )
211 #define DTRACE_COND(cond,ctx,channel,...)    { if( cond ) ctx->dtrace<true>( channel, __VA_ARGS__ ); }
212 #define DTRACE_BLOCK(...)                    dtrace_block(__VA_ARGS__)
213 #define DTRACE_FRAME_BLOCKWISE(...)          dtrace_frame_blockwise(__VA_ARGS__)
214 #define DTRACE_GET_COUNTER(ctx,channel)      ctx->getChannelCounter(channel)
215 
216 #include "CommonLib/Rom.h"
217 
tracing_init(std::string & sTracingFile,std::string & sTracingRule)218 inline CDTrace* tracing_init( std::string& sTracingFile, std::string& sTracingRule )
219 {
220   dtrace_channel next_channels[] =
221   {
222     _CNL_DEF( D_COMMON ),
223     _CNL_DEF( D_HEADER ),
224     _CNL_DEF( D_NALUNITHEADER ),
225     _CNL_DEF( D_RPSINFO ),
226     _CNL_DEF( D_REC_CB_LUMA ),
227     _CNL_DEF( D_REC_CB_CHROMA ),
228     _CNL_DEF( D_REC_CB_LUMA_LF ),
229     _CNL_DEF( D_REC_CB_CHROMA_LF ),
230     _CNL_DEF( D_REC_CB_LUMA_SAO ),
231     _CNL_DEF( D_REC_CB_CHROMA_SAO ),
232     _CNL_DEF( D_REC_CB_LUMA_ALF ),
233     _CNL_DEF( D_REC_CB_CHROMA_ALF ),
234     _CNL_DEF( D_ME ),
235     _CNL_DEF( D_CABAC ),
236     _CNL_DEF( D_SYNTAX ),
237     _CNL_DEF( D_SYNTAX_RESI ),
238     _CNL_DEF( D_BEST_MODE ),
239     _CNL_DEF( D_MODE_COST ),
240     _CNL_DEF( D_QP_PRED ),
241     _CNL_DEF( D_DQP ),
242     _CNL_DEF( D_QP ),
243     _CNL_DEF( D_QP_PER_CTU ),
244     _CNL_DEF( D_MISC ),
245     _CNL_DEF( D_DECISIONTREE ),
246     _CNL_DEF( D_TU_ABS_SUM ),
247     _CNL_DEF( D_EST_FRAC_BITS ),
248     _CNL_DEF( D_INTRA_COST ),
249     _CNL_DEF( D_PRED ),
250     _CNL_DEF( D_RESIDUALS ),
251     _CNL_DEF( D_TCOEFF ),
252     _CNL_DEF( D_RDOQ ),
253     _CNL_DEF( D_RDOQ_MORE ),
254     _CNL_DEF( D_RDOQ_COST ),
255     _CNL_DEF( D_TMP ),
256     _CNL_DEF( D_CRC ),
257     _CNL_DEF( D_CRC_LF )
258   };
259   dtrace_channels_t channels( next_channels, &next_channels[sizeof( next_channels ) / sizeof( next_channels[0] )] );
260 
261   if( !sTracingFile.empty() || !sTracingRule.empty() )
262   {
263     msg( VERBOSE, "\n" );
264     msg( VERBOSE, "Tracing is enabled: %s : %s\n", sTracingFile.c_str(), sTracingRule.c_str() );
265   }
266 
267   CDTrace *pDtrace = new CDTrace( sTracingFile, sTracingRule, channels );
268   if( pDtrace->getLastError() )
269   {
270     msg( WARNING, "%s\n", pDtrace->getErrMessage().c_str() );
271     //return NULL;
272   }
273 
274   return pDtrace;
275 }
276 
277 #else
278 
279 #define DTRACE(ctx,channel,...)               {}
280 #define DTRACE_WITHOUT_COUNT(ctx,channel,...) {}
281 #define DTRACE_DECR_COUNTER(ctx,channel)      {}
282 #define DTRACE_UPDATE(ctx,s)                  {}
283 #define DTRACE_COND(cond,level,...)           {}
284 #define DTRACE_REPEAT(ctx,channel,times,...)  {}
285 #define DTRACE_SET(_dst,_src)  (_dst)=(_src)
286 #define DTRACE_BLOCK(...)                     {}
287 #define DTRACE_FRAME_BLOCKWISE(...)           {}
288 #define DTRACE_GET_COUNTER(ctx,channel)       {}
289 
290 #endif
291 
292 }
293