Newer
Older
/* 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) 2010-2020, ITU/ISO/IEC
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
* 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 dtrace_blockstatistics.cpp
* \brief DTrace block statistcis support for next software
*/
#include "dtrace_blockstatistics.h"
#include "dtrace.h"
#include "dtrace_next.h"
#include "CommonLib/Unit.h"
#include "CommonLib/Picture.h"
#include "CommonLib/UnitTools.h"
//#include "CommonLib/CodingStructure.h"
#define BLOCK_STATS_POLYGON_MIN_POINTS 3
#define BLOCK_STATS_POLYGON_MAX_POINTS 5
#if K0149_BLOCK_STATISTICS
std::string GetBlockStatisticName(BlockStatistic statistic)
{
auto statisticIterator = blockstatistic2description.find(statistic);
// enforces that all delcared statistic enum items are also part of the map
assert(statisticIterator != blockstatistic2description.end() && "A block statistics declared in the enum is missing in the map for statistic description.");
return std::get<0>(statisticIterator->second);
}
std::string GetBlockStatisticTypeString(BlockStatistic statistic)
{
auto statisticIterator = blockstatistic2description.find(statistic);
// enforces that all delcared statistic enum items are also part of the map
assert(statisticIterator != blockstatistic2description.end() && "A block statistics declared in the enum is missing in the map for statistic description.");
BlockStatisticType statisticType = std::get<1>(statisticIterator->second);
switch (statisticType) {
case BlockStatisticType::Flag:
return std::string("Flag");
break;
case BlockStatisticType::Vector:
return std::string("Vector");
break;
case BlockStatisticType::Integer:
return std::string("Integer");
break;
case BlockStatisticType::AffineTFVectors:
return std::string("AffineTFVectors");
break;
case BlockStatisticType::Line:
return std::string("Line");
break;
case BlockStatisticType::FlagPolygon:
return std::string("FlagPolygon");
break;
case BlockStatisticType::VectorPolygon:
return std::string("VectorPolygon");
break;
case BlockStatisticType::IntegerPolygon:
return std::string("IntegerPolygon");
break;
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
default:
assert(0);
break;
}
return std::string();
}
std::string GetBlockStatisticTypeSpecificInfo(BlockStatistic statistic)
{
auto statisticIterator = blockstatistic2description.find(statistic);
// enforces that all delcared statistic enum items are also part of the map
assert(statisticIterator != blockstatistic2description.end() && "A block statistics declared in the enum is missing in the map for statistic description.");
return std::get<2>(statisticIterator->second);
}
void CDTrace::dtrace_block_scalar( int k, const CodingStructure &cs, std::string stat_type, signed value )
{
#if BLOCK_STATS_AS_CSV
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, cs.area.lx(), cs.area.ly(), cs.area.lwidth(), cs.area.lheight(), stat_type.c_str(), value );
#else
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, cs.area.lx(), cs.area.ly(), cs.area.lwidth(), cs.area.lheight(), stat_type.c_str(), value );
#endif
}
void CDTrace::dtrace_block_scalar( int k, const CodingUnit &cu, std::string stat_type, signed value, bool isChroma /*= false*/ )
{
const CodingStructure& cs = *cu.cs;
#if BLOCK_STATS_AS_CSV
if(isChroma)
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, cu.Cb().x*2, cu.Cb().y*2, cu.Cb().width*2, cu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), value );
}
#else
if(isChroma)
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, cu.Cb().x*2, cu.Cb().y*2, cu.Cb().width*2, cu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), value );
}
#endif
}
void CDTrace::dtrace_block_vector( int k, const CodingUnit &cu, std::string stat_type, signed val_x, signed val_y )
{
const CodingStructure& cs = *cu.cs;
#if BLOCK_STATS_AS_CSV
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n", cs.picture->poc, cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), val_x, val_y );
#else
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n", cs.picture->poc, cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), val_x, val_y );
#endif
}
void CDTrace::dtrace_block_scalar( int k, const PredictionUnit &pu, std::string stat_type, signed value, bool isChroma /*= false*/ )
{
const CodingStructure& cs = *pu.cs;
#if BLOCK_STATS_AS_CSV
if(isChroma)
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, pu.Cb().x*2, pu.Cb().y*2, pu.Cb().width*2, pu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(), value );
}
#else
if(isChroma)
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, pu.Cb().x*2, pu.Cb().y*2, pu.Cb().width*2, pu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(), value );
}
#endif
}
void CDTrace::dtrace_block_vector( int k, const PredictionUnit &pu, std::string stat_type, signed val_x, signed val_y, bool isChroma /*= false*/ )
{
const CodingStructure& cs = *pu.cs;
#if BLOCK_STATS_AS_CSV
if(isChroma)
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n", cs.picture->poc, pu.Cb().x*2, pu.Cb().y*2, pu.Cb().width*2, pu.Cb().height*2, stat_type.c_str(), val_x*2, val_y*2 );
}
else
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n", cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(), val_x, val_y );
}
if(isChroma)
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n", cs.picture->poc, pu.Cb().x*2, pu.Cb().y*2, pu.Cb().width*2, pu.Cb().height*2, stat_type.c_str(), val_x*2, val_y*2 );
}
else
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n", cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(), val_x, val_y );
}
#endif
}
void CDTrace::dtrace_block_scalar(int k, const TransformUnit &tu, std::string stat_type, signed value, bool isChroma /*= false*/ )
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
const CodingStructure& cs = *tu.cs;
#if BLOCK_STATS_AS_CSV
if(isChroma)
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, tu.Cb().x*2, tu.Cb().y*2, tu.Cb().width*2, tu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%d\n", cs.picture->poc, tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), stat_type.c_str(), value );
}
#else
if(isChroma)
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, tu.Cb().x*2, tu.Cb().y*2, tu.Cb().width*2, tu.Cb().height*2, stat_type.c_str(), value );
}
else
{
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s=%d\n", cs.picture->poc, tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), stat_type.c_str(), value );
}
#endif
}
void CDTrace::dtrace_block_vector(int k, const TransformUnit &tu, std::string stat_type, signed val_x, signed val_y)
{
const CodingStructure& cs = *tu.cs;
#if BLOCK_STATS_AS_CSV
dtrace<false>(k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n", cs.picture->poc, tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), stat_type.c_str(), val_x, val_y);
#else
dtrace<false>(k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n", cs.picture->poc, tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), stat_type.c_str(), val_x, val_y);
#endif
}
void CDTrace::dtrace_block_affinetf( int k, const PredictionUnit &pu, std::string stat_type, signed val_x0, signed val_y0, signed val_x1, signed val_y1, signed val_x2, signed val_y2 )
{
const CodingStructure& cs = *pu.cs;
#if BLOCK_STATS_AS_CSV
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d;%4d;%4d;%4d;%4d\n",
cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(),
val_x0, val_y0, val_x1, val_y1 , val_x2, val_y2 );
#else
dtrace<false>( k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d,%4d,%4d,%4d,%4d}\n",
cs.picture->poc, pu.lx(), pu.ly(), pu.lwidth(), pu.lheight(), stat_type.c_str(),
val_x0, val_y0, val_x1, val_y1 , val_x2, val_y2 );
#endif
}
void CDTrace::dtrace_block_line(int k, const CodingUnit &cu, std::string stat_type, int x0, int y0, int x1, int y1)
{
#if BLOCK_STATS_AS_CSV
dtrace<false>( k, "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d;%4d;%4d;\n", cu.slice->getPOC(), cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), x0, y0, x1, y1);
#else
dtrace<false>(k, "BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d,%4d,%4d}\n", cu.slice->getPOC(), cu.lx(), cu.ly(), cu.lwidth(), cu.lheight(), stat_type.c_str(), x0, y0, x1, y1);
}
void CDTrace::dtrace_polygon_scalar(int k, int poc, const std::vector<Position> &polygon, std::string stat_type, signed value)
{
assert(polygon.size() >= BLOCK_STATS_POLYGON_MIN_POINTS && "Not enough points to from polygon!");
assert(polygon.size() <= BLOCK_STATS_POLYGON_MAX_POINTS && "Too many points. Unsupported polygon!");
std::string polygonDescription;
#if BLOCK_STATS_AS_CSV
for (auto position : polygon)
{
polygonDescription += std::to_string(position.x) + ";" + std::to_string(position.y) + ";";
}
dtrace<false>( k, "BlockStat;%d;%s%s;%d\n",poc, polygonDescription.c_str(), stat_type.c_str(), value);
#else
for (auto position : polygon)
{
polygonDescription += "(" + std::to_string(position.x) + ", " + std::to_string(position.y) + ")--";
}
dtrace<false>(k, "BlockStat: POC %d @[%s] %s=%d\n", poc, polygonDescription.c_str(), stat_type.c_str(), value);
}
void CDTrace::dtrace_polygon_vector(int k, int poc, const std::vector<Position> &polygon, std::string stat_type, signed val_x, signed val_y)
{
assert(polygon.size() >= BLOCK_STATS_POLYGON_MIN_POINTS && "Not enough points to from polygon!");
assert(polygon.size() <= BLOCK_STATS_POLYGON_MAX_POINTS && "Too many points. Unsupported polygon!");
std::string polygonDescription;
#if BLOCK_STATS_AS_CSV
for (auto position : polygon)
{
polygonDescription += std::to_string(position.x) + ";" + std::to_string(position.y) + ";";
}
dtrace<false>( k, "BlockStat;%d;%s%s;%d;%d\n",poc, polygonDescription.c_str(), stat_type.c_str(), val_x, val_y);
#else
for (auto position : polygon)
{
polygonDescription += "(" + std::to_string(position.x) + ", " + std::to_string(position.y) + ")--";
}
dtrace<false>(k, "BlockStat: POC %d @[%s] %s={%4d,%4d}\n", poc, polygonDescription.c_str(), stat_type.c_str(), val_x, val_y);
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
void retrieveGeoPolygons(const CodingUnit& cu, std::vector<Position> (&geoPartitions)[2], Position (&linePositions)[2])
{
// adapted code from interpolation filter to find geo partition polygons like this:
// use SAD mask, which should clearly partition the two polygons.
// loop over boundary pixels and find positions where there is a change, these should be the polygon corners
static bool isInitialized = false;
static std::vector<Position> allGeoPartitionings[GEO_NUM_CU_SIZE][GEO_NUM_CU_SIZE][GEO_NUM_PARTITION_MODE][2];
static Position allGeoPartitioningLines[GEO_NUM_CU_SIZE][GEO_NUM_CU_SIZE][GEO_NUM_PARTITION_MODE][2];
if(!isInitialized)
{
for( int hIdx = 0; hIdx < GEO_NUM_CU_SIZE; hIdx++ )
{
int16_t height = 1 << ( hIdx + GEO_MIN_CU_LOG2);
for( int wIdx = 0; wIdx < GEO_NUM_CU_SIZE; wIdx++ )
{
int16_t width = 1 << (wIdx + GEO_MIN_CU_LOG2);
for( int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++ )
{
int16_t angle = g_GeoParams[splitDir][0];
int maskStride = 0;
int stepX = 1;
Pel* SADmask;
if (g_angle2mirror[angle] == 2)
{
maskStride = -GEO_WEIGHT_MASK_SIZE;
SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][(GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][1]) * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]];
}
else if (g_angle2mirror[angle] == 1)
{
stepX = -1;
maskStride = GEO_WEIGHT_MASK_SIZE;
SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + (GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][0])];
}
else
{
maskStride = GEO_WEIGHT_MASK_SIZE;
SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]];
}
int currentPartition = 0;
std::vector<Pel> boundaryOfMask; // for debugging
Area partitionArea = Area(0, 0, width, height);
Position TL = partitionArea.topLeft();
Position TR = partitionArea.topRight(); TR = TR.offset(1, 0);
Position BL = partitionArea.bottomLeft(); BL = BL.offset(0, 1);
Position BR = partitionArea.bottomRight(); BR = BR.offset(1, 1);
std::vector<Position> oneGeoPartitioning[2];
Position oneGeoPartitioningLine[2];
// corner of block is a corner of the first partition
oneGeoPartitioning[currentPartition].push_back(TL);
// process top boundary
for( int x = 0; x < width-1; x++ )
{
boundaryOfMask.push_back(*SADmask);
if(*SADmask != *(SADmask+stepX))
{
// found a change of partitions, it is a corner of both partition polygons
oneGeoPartitioning[currentPartition].push_back(Position(TL.x + x, TL.y));
oneGeoPartitioningLine[currentPartition] = Position(TL.x + x, TL.y);
currentPartition ^= 0x01;
oneGeoPartitioning[currentPartition].push_back(Position(TL.x + x, TL.y));
}
SADmask += stepX;
}
// corner of block is a corner of the current partition
oneGeoPartitioning[currentPartition].push_back(TR);
// process right boundary
for( int y = 0; y < height-1; y++ )
{
boundaryOfMask.push_back(*SADmask);
if(*SADmask != *(SADmask+maskStride))
{
// found a change of partitions, it is a corner of both partition polygons
oneGeoPartitioning[currentPartition].push_back(Position(TR.x, TR.y + y));
oneGeoPartitioningLine[currentPartition] = Position(TR.x, TR.y + y);
currentPartition ^= 0x01;
oneGeoPartitioning[currentPartition].push_back(Position(TR.x, TR.y + y));
}
SADmask += maskStride;
}
// corner of block is a corner of the current partition
oneGeoPartitioning[currentPartition].push_back(BR);
// process bottom boundary
for( int x = width-1; x > 0; x-- )
{
boundaryOfMask.push_back(*SADmask);
if(*SADmask != *(SADmask-stepX))
{
// found a change of partitions, it is a corner of both partition polygons
oneGeoPartitioning[currentPartition].push_back(Position(BL.x + x, BL.y));
oneGeoPartitioningLine[currentPartition] = Position(BL.x + x, BL.y);
currentPartition ^= 0x01;
oneGeoPartitioning[currentPartition].push_back(Position(BL.x + x, BL.y));
}
SADmask -= stepX;
}
// corner of block is a corner of the current partition
oneGeoPartitioning[currentPartition].push_back(BL);
// process left boundary
for( int y = height-1; y > 0; y-- )
{
boundaryOfMask.push_back(*SADmask);
if(*SADmask != *(SADmask-maskStride))
{
// found a change of partitions, it is a corner of both partition polygons
oneGeoPartitioning[currentPartition].push_back(Position(TL.x, TL.y + y));
oneGeoPartitioningLine[currentPartition] = Position(TL.x, TL.y + y);
currentPartition ^= 0x01;
oneGeoPartitioning[currentPartition].push_back(Position(TL.x, TL.y + y));
}
SADmask -= maskStride;
}
// corner of block is a corner of the current partition
oneGeoPartitioning[currentPartition].push_back(TL);
// remove duplicate points
for( auto geoPartIdx = 0; geoPartIdx < 2; geoPartIdx++)
{
// this will only remove consecutive duplicates
auto last = std::unique(oneGeoPartitioning[geoPartIdx].begin(), oneGeoPartitioning[geoPartIdx].end());
oneGeoPartitioning[geoPartIdx].erase(last, oneGeoPartitioning[geoPartIdx].end());
// also check if first and last are the same
if(oneGeoPartitioning[geoPartIdx].front() == oneGeoPartitioning[geoPartIdx].back())
{
oneGeoPartitioning[geoPartIdx].pop_back();
}
CHECK(!(oneGeoPartitioning[geoPartIdx].size() > 2 && oneGeoPartitioning[geoPartIdx].size() < 6), "Invalid geo partition shape. Polygon should have between 3 and 5 corners.");
}
allGeoPartitionings[hIdx][wIdx][splitDir][0] = oneGeoPartitioning[0];
allGeoPartitionings[hIdx][wIdx][splitDir][1] = oneGeoPartitioning[1];
allGeoPartitioningLines[hIdx][wIdx][splitDir][0] = oneGeoPartitioningLine[0];
allGeoPartitioningLines[hIdx][wIdx][splitDir][1] = oneGeoPartitioningLine[1];
}
}
}
isInitialized = true;
}
const uint8_t splitDir = cu.firstPU->geoSplitDir;
int16_t wIdx = floorLog2(cu.lwidth()) - GEO_MIN_CU_LOG2;
int16_t hIdx = floorLog2(cu.lheight()) - GEO_MIN_CU_LOG2;
Position TL = cu.Y().topLeft();
geoPartitions[0] = allGeoPartitionings[hIdx][wIdx][splitDir][0];
geoPartitions[1] = allGeoPartitionings[hIdx][wIdx][splitDir][1];
linePositions[0] = allGeoPartitioningLines[hIdx][wIdx][splitDir][0];
linePositions[1] = allGeoPartitioningLines[hIdx][wIdx][splitDir][1];
// offset the partitioning to the current cu
for( auto geoPartIdx = 0; geoPartIdx < 2; geoPartIdx++)
{
for( Position &polygonCorner : geoPartitions[geoPartIdx])
{
polygonCorner.repositionTo(polygonCorner.offset(TL));
}
}
}
std::queue<MergeCtx> geoMergeCtxtsOfCurrentCtu;
void storeGeoMergeCtx(MergeCtx geoMergeCtx)
{
geoMergeCtxtsOfCurrentCtu.push(geoMergeCtx);
}
void writeBlockStatisticsHeader(const SPS *sps)
{
static bool has_header_been_written = false;
if (has_header_been_written)
{
return;
}
// only write header when block statistics are used
bool write_blockstatistics = g_trace_ctx->isChannelActive( D_BLOCK_STATISTICS_ALL) || g_trace_ctx->isChannelActive( D_BLOCK_STATISTICS_CODED);
if(!write_blockstatistics)
{
return;
}
DTRACE_HEADER( g_trace_ctx, "# VTMBMS Block Statistics\n");
// sequence info
DTRACE_HEADER( g_trace_ctx, "# Sequence size: [%dx %d]\n", sps->getMaxPicWidthInLumaSamples(), sps->getMaxPicHeightInLumaSamples() );
// list statistics
for( auto i = static_cast<int>(BlockStatistic::PredMode); i < static_cast<int>(BlockStatistic::NumBlockStatistics); i++)
{
BlockStatistic statistic = BlockStatistic(i);
std::string statitic_name = GetBlockStatisticName(statistic);
std::string statitic_type = GetBlockStatisticTypeString(statistic);
std::string statitic_type_specific_info = GetBlockStatisticTypeSpecificInfo(statistic);
DTRACE_HEADER( g_trace_ctx, "# Block Statistic Type: %s; %s; %s\n", statitic_name.c_str(), statitic_type.c_str(), statitic_type_specific_info.c_str());
}
has_header_been_written = true;
}
void getAndStoreBlockStatistics(const CodingStructure& cs, const UnitArea& ctuArea)
{
// two differemt behaviors, depending on which information is needed
bool writeAll = g_trace_ctx->isChannelActive( D_BLOCK_STATISTICS_ALL);
bool writeCoded = g_trace_ctx->isChannelActive( D_BLOCK_STATISTICS_CODED);
CHECK(writeAll && writeCoded, "Either used D_BLOCK_STATISTICS_ALL or D_BLOCK_STATISTICS_CODED. Not both at once!")
if (writeCoded)
writeAllCodedData(cs, ctuArea); // this will write out important cu-based data, only if it is actually decoded and used
else if (writeAll)
writeAllData(cs, ctuArea); // this will write out all inter- or intra-prediction related data
}
void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
{
const int maxNumChannelType = cs.pcv->chrFormat != CHROMA_400 && CS::isDualITree( cs ) ? 2 : 1;
const int nShift = MV_FRACTIONAL_BITS_DIFF;
const int nOffset = 1 << (nShift - 1);
for( int ch = 0; ch < maxNumChannelType; ch++ )
{
const ChannelType chType = ChannelType( ch );
for( const CodingUnit &cu : cs.traverseCUs( CS::getArea( cs, ctuArea, chType ), chType ) )
{
if( chType == CHANNEL_TYPE_LUMA )
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::PredMode), cu.predMode);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::Depth), cu.depth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::QT_Depth), cu.qtDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BT_Depth), cu.btDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::MT_Depth), cu.mtDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::ChromaQPAdj), cu.chromaQpAdj);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::QP), cu.qp);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SplitSeries), (int)cu.splitSeries);
// skip flag
if (!cs.slice->isIntra())
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SkipFlag), cu.skip);
}
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BDPCM), cu.bdpcmMode);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BDPCMChroma), cu.bdpcmModeChroma);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::TileIdx), cu.tileIdx);
Johannes Sauer
committed
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::IndependentSliceIdx), cu.slice->getIndependentSliceIdx());
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::LFNSTIdx), cu.lfnstIdx);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::MMVDSkipFlag), cu.mmvdSkip);
}
else if( chType == CHANNEL_TYPE_CHROMA )
{
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::Depth_Chroma), cu.depth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::QT_Depth_Chroma), cu.qtDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BT_Depth_Chroma), cu.btDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::MT_Depth_Chroma), cu.mtDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::ChromaQPAdj_Chroma), cu.chromaQpAdj);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::QP_Chroma), cu.qp);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SplitSeries_Chroma), (int)cu.splitSeries);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BDPCMChroma), cu.bdpcmModeChroma);
}
switch( cu.predMode )
{
case MODE_INTER:
{
for( const PredictionUnit &pu : CU::traversePUs( cu ) )
{
if (!pu.cu->skip)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MergeFlag), pu.mergeFlag);
}
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::RegularMergeFlag), pu.regularMergeFlag);
if( pu.mergeFlag )
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MergeIdx), pu.mergeIdx);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MergeType), pu.mergeType);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeFlag), pu.mmvdMergeFlag);
if (cu.mmvdSkip || pu.mmvdMergeFlag)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeIdx), pu.mmvdMergeIdx);
}
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::CiipFlag), pu.ciipFlag);
if (pu.ciipFlag)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::Luma_IntraMode), pu.intraDir[COMPONENT_Y]);
}
}
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::AffineFlag), pu.cu->affine);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::AffineType), pu.cu->affineType);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::InterDir), pu.interDir);
if (pu.interDir != 2 /* PRED_L1 */)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVPIdxL0), pu.mvpIdx[REF_PIC_LIST_0]);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::RefIdxL0), pu.refIdx[REF_PIC_LIST_0]);
}
if (pu.interDir != 1 /* PRED_L1 */)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVPIdxL1), pu.mvpIdx[REF_PIC_LIST_1]);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::RefIdxL1), pu.refIdx[REF_PIC_LIST_1]);
}
if (!pu.cu->affine && !pu.cu->geoFlag)
{
if (pu.interDir != 2 /* PRED_L1 */)
{
Mv mv = pu.mv[REF_PIC_LIST_0];
Mv mvd = pu.mvd[REF_PIC_LIST_0];
mv.hor = mv.hor >= 0 ? (mv.hor + nOffset) >> nShift : -((-mv.hor + nOffset) >> nShift);
mv.ver = mv.ver >= 0 ? (mv.ver + nOffset) >> nShift : -((-mv.ver + nOffset) >> nShift);
mvd.hor = mvd.hor >= 0 ? (mvd.hor + nOffset) >> nShift : -((-mvd.hor + nOffset) >> nShift);
mvd.ver = mvd.ver >= 0 ? (mvd.ver + nOffset) >> nShift : -((-mvd.ver + nOffset) >> nShift);
DTRACE_BLOCK_VECTOR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVDL0), mvd.hor, mvd.ver);
DTRACE_BLOCK_VECTOR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVL0), mv.hor, mv.ver);
}
if (pu.interDir != 1 /* PRED_L1 */)
{
Mv mv = pu.mv[REF_PIC_LIST_1];
Mv mvd = pu.mvd[REF_PIC_LIST_1];
mv.hor = mv.hor >= 0 ? (mv.hor + nOffset) >> nShift : -((-mv.hor + nOffset) >> nShift);
mv.ver = mv.ver >= 0 ? (mv.ver + nOffset) >> nShift : -((-mv.ver + nOffset) >> nShift);
mvd.hor = mvd.hor >= 0 ? (mvd.hor + nOffset) >> nShift : -((-mvd.hor + nOffset) >> nShift);
mvd.ver = mvd.ver >= 0 ? (mvd.ver + nOffset) >> nShift : -((-mvd.ver + nOffset) >> nShift);
DTRACE_BLOCK_VECTOR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVDL1), mvd.hor, mvd.ver);
DTRACE_BLOCK_VECTOR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MVL1), mv.hor, mv.ver);
}
}
{
if (pu.interDir != 2 /* PRED_L1 */)
{
Mv mv[3];
const CMotionBuf &mb = pu.getMotionBuf();
mv[0] = mb.at(0, 0).mv[REF_PIC_LIST_0];
mv[1] = mb.at(mb.width - 1, 0).mv[REF_PIC_LIST_0];
mv[2] = mb.at(0, mb.height - 1).mv[REF_PIC_LIST_0];
// motion vectors should use low precision or they will appear to large
mv[0].hor = mv[0].hor >= 0 ? (mv[0].hor + nOffset) >> nShift : -((-mv[0].hor + nOffset) >> nShift);
mv[0].ver = mv[0].ver >= 0 ? (mv[0].ver + nOffset) >> nShift : -((-mv[0].ver + nOffset) >> nShift);
mv[1].hor = mv[1].hor >= 0 ? (mv[1].hor + nOffset) >> nShift : -((-mv[1].hor + nOffset) >> nShift);
mv[1].ver = mv[1].ver >= 0 ? (mv[1].ver + nOffset) >> nShift : -((-mv[1].ver + nOffset) >> nShift);
mv[2].hor = mv[2].hor >= 0 ? (mv[2].hor + nOffset) >> nShift : -((-mv[2].hor + nOffset) >> nShift);
mv[2].ver = mv[2].ver >= 0 ? (mv[2].ver + nOffset) >> nShift : -((-mv[2].ver + nOffset) >> nShift);
DTRACE_BLOCK_AFFINETF(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::AffineMVL0), mv[0].hor, mv[0].ver, mv[1].hor, mv[1].ver, mv[2].hor, mv[2].ver);
}
if (pu.interDir != 1 /* PRED_L1 */)
{
Mv mv[3];
const CMotionBuf &mb = pu.getMotionBuf();
mv[0] = mb.at(0, 0).mv[REF_PIC_LIST_1];
mv[1] = mb.at(mb.width - 1, 0).mv[REF_PIC_LIST_1];
mv[2] = mb.at(0, mb.height - 1).mv[REF_PIC_LIST_1];
// motion vectors should use low precision or they will appear to large
mv[0].hor = mv[0].hor >= 0 ? (mv[0].hor + nOffset) >> nShift : -((-mv[0].hor + nOffset) >> nShift);
mv[0].ver = mv[0].ver >= 0 ? (mv[0].ver + nOffset) >> nShift : -((-mv[0].ver + nOffset) >> nShift);
mv[1].hor = mv[1].hor >= 0 ? (mv[1].hor + nOffset) >> nShift : -((-mv[1].hor + nOffset) >> nShift);
mv[1].ver = mv[1].ver >= 0 ? (mv[1].ver + nOffset) >> nShift : -((-mv[1].ver + nOffset) >> nShift);
mv[2].hor = mv[2].hor >= 0 ? (mv[2].hor + nOffset) >> nShift : -((-mv[2].hor + nOffset) >> nShift);
mv[2].ver = mv[2].ver >= 0 ? (mv[2].ver + nOffset) >> nShift : -((-mv[2].ver + nOffset) >> nShift);
DTRACE_BLOCK_AFFINETF(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::AffineMVL1), mv[0].hor, mv[0].ver, mv[1].hor, mv[1].ver, mv[2].hor, mv[2].ver);
}
}
// tracing Motion buffers
CMotionBuf mb = pu.getMotionBuf();
// todo: assuming granulatiry == 4. can it be derived?
for( int y = 0; y < mb.height; y++ )
{
for( int x = 0; x < mb.width; x++ )
{
const MotionInfo &pixMi = mb.at( x, y );
if( pixMi.interDir == 1)
{
const Mv mv = pixMi.mv[REF_PIC_LIST_0];
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL0).c_str(),
mv.hor,
mv.ver);
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL0).c_str(),
mv.hor,
mv.ver);
}
else if( pixMi.interDir == 2)
{
const Mv mv = pixMi.mv[REF_PIC_LIST_1];
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL1).c_str(),
mv.hor,
mv.ver);
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL1).c_str(),
mv.hor,
mv.ver);
}
else if( pixMi.interDir == 3)
{
{
const Mv mv = pixMi.mv[REF_PIC_LIST_0];
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL0).c_str(),
mv.hor,
mv.ver);
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL0).c_str(),
mv.hor,
mv.ver);
{
const Mv mv = pixMi.mv[REF_PIC_LIST_1];
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL1).c_str(),
mv.hor,
mv.ver);
g_trace_ctx->dtrace<false>(
D_BLOCK_STATISTICS_ALL,
"BlockStat: POC %d @(%4d,%4d) [%2dx%2d] %s={%4d,%4d}\n",
cs.picture->poc,
pu.lx() + 4*x,
pu.ly() + 4*y,
4,
4,
GetBlockStatisticName(BlockStatistic::MotionBufL1).c_str(),
mv.hor,
mv.ver);
if (cu.geoFlag)
{
const uint8_t candIdx0 = cu.firstPU->geoMergeIdx0;
const uint8_t candIdx1 = cu.firstPU->geoMergeIdx1;
std::vector<Position> geoPartitions[2];
Position linePositions[2];
retrieveGeoPolygons(cu, geoPartitions, linePositions);
DTRACE_LINE(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::GeoPartitioning), linePositions[0].x, linePositions[0].y, linePositions[1].x, linePositions[1].y);
if(geoMergeCtxtsOfCurrentCtu.size() > 0)
// Geo partition MVs can only be stored when using the statistics with the decoder. Encoder is not supported
{
MergeCtx geoMrgCtx = geoMergeCtxtsOfCurrentCtu.front();
geoMergeCtxtsOfCurrentCtu.pop();
// first partition
{
PredictionUnit tmpPu = *cu.firstPU;
geoMrgCtx.setMergeInfo( tmpPu, candIdx0 );
const int geoPartIdx = 0;
for (int refIdx = 0; refIdx < 2; refIdx++)
{
if (tmpPu.refIdx[refIdx] != -1)
{
Mv tmpMv = tmpPu.mv[refIdx];
tmpMv.hor = tmpMv.hor >= 0 ? (tmpMv.hor + nOffset) >> nShift : -((-tmpMv.hor + nOffset) >> nShift);
tmpMv.ver = tmpMv.ver >= 0 ? (tmpMv.ver + nOffset) >> nShift : -((-tmpMv.ver + nOffset) >> nShift);
DTRACE_POLYGON_VECTOR(g_trace_ctx,
D_BLOCK_STATISTICS_ALL,
cu.slice->getPOC(),
geoPartitions[geoPartIdx],
GetBlockStatisticName(refIdx==0?BlockStatistic::GeoMVL0:BlockStatistic::GeoMVL1),
tmpMv.hor,
tmpMv.ver
);
}
}
}
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
// second partition
{
PredictionUnit tmpPu = *cu.firstPU;
geoMrgCtx.setMergeInfo( tmpPu, candIdx1 );
const int geoPartIdx = 1;
{
for (int refIdx = 0; refIdx < 2; refIdx++)
{
if (tmpPu.refIdx[refIdx] != -1)
{
Mv tmpMv = tmpPu.mv[refIdx];
tmpMv.hor = tmpMv.hor >= 0 ? (tmpMv.hor + nOffset) >> nShift : -((-tmpMv.hor + nOffset) >> nShift);
tmpMv.ver = tmpMv.ver >= 0 ? (tmpMv.ver + nOffset) >> nShift : -((-tmpMv.ver + nOffset) >> nShift);
DTRACE_POLYGON_VECTOR(g_trace_ctx,
D_BLOCK_STATISTICS_ALL,
cu.slice->getPOC(),
geoPartitions[geoPartIdx],
GetBlockStatisticName(refIdx==0?BlockStatistic::GeoMVL0:BlockStatistic::GeoMVL1),
tmpMv.hor,
tmpMv.ver
);
}
}
}
}
}
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SMVDFlag), cu.smvdMode);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::IMVMode), cu.imv);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::RootCbf), cu.rootCbf);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::BCWIndex), cu.BcwIdx);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SbtIdx), cu.getSbtIdx());
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::SbtPos), cu.getSbtPos());
}
break;
case MODE_INTRA:
{
if(chType == CHANNEL_TYPE_LUMA)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::MIPFlag), cu.mipFlag);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu, GetBlockStatisticName(BlockStatistic::ISPMode), cu.ispMode);
}
const uint32_t numChType = ::getNumberValidChannels( cu.chromaFormat );
for( uint32_t chType = CHANNEL_TYPE_LUMA; chType < numChType; chType++ )
{
if( cu.blocks[chType].valid() )
{
for( const PredictionUnit &pu : CU::traversePUs( cu ) )
{
if( isLuma( ChannelType( chType ) ) )
{
const uint32_t uiChFinalMode = PU::getFinalIntraMode( pu, ChannelType( chType ) );
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::Luma_IntraMode), uiChFinalMode);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MultiRefIdx), pu.multiRefIdx);
}
else
{
const uint32_t uiChFinalMode = PU::getFinalIntraMode( pu, ChannelType( chType ) );
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::Chroma_IntraMode), uiChFinalMode);
assert(0);
}
}
}
}
break;
default:
THROW( "Invalid prediction mode" );
break;
}
for (const TransformUnit &tu : CU::traverseTUs(cu))
{
if (tu.Y().valid())
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::Cbf_Y), tu.cbf[COMPONENT_Y]);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::MTSIdx_Y), tu.mtsIdx[COMPONENT_Y]);
if ( tu.Cb().valid() )
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::JointCbCr), tu.jointCbCr);
}
if( !(cu.chromaFormat == CHROMA_400 || (cu.isSepTree() && cu.chType == CHANNEL_TYPE_LUMA)) )
{
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::Cbf_Cb), tu.cbf[COMPONENT_Cb]);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::Cbf_Cr), tu.cbf[COMPONENT_Cr]);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::MTSIdx_Cb), tu.mtsIdx[COMPONENT_Cb]);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_ALL, tu, GetBlockStatisticName(BlockStatistic::MTSIdx_Cr), tu.mtsIdx[COMPONENT_Cr]);
}
}
}
CHECK(geoMergeCtxtsOfCurrentCtu.size() != 0, "Did not use all pushed back geo merge contexts. Should not be possible!");
}
void writeAllCodedData(const CodingStructure & cs, const UnitArea & ctuArea)
{
const int nShift = MV_FRACTIONAL_BITS_DIFF;
const int nOffset = 1 << (nShift - 1);
const int maxNumChannelType = cs.pcv->chrFormat != CHROMA_400 && CS::isDualITree(cs) ? 2 : 1;
for (int ch = 0; ch < maxNumChannelType; ch++)
{
const ChannelType chType = ChannelType(ch);
for (const CodingUnit &cu : cs.traverseCUs(CS::getArea(cs, ctuArea, chType), chType))
{
if( chType == CHANNEL_TYPE_LUMA )
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::Depth), cu.depth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::QT_Depth), cu.qtDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::BT_Depth), cu.btDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::MT_Depth), cu.mtDepth);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::ChromaQPAdj), cu.chromaQpAdj);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::QP), cu.qp);
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::SplitSeries), (int)cu.splitSeries);
// skip flag
if (!cs.slice->isIntra() && cu.Y().valid())
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::SkipFlag), cu.skip);
if (cu.skip)
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::MMVDSkipFlag), cu.mmvdSkip);
}
}
// prediction mode and partitioning data
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::PredMode), cu.predMode);
}
else if (chType == CHANNEL_TYPE_CHROMA )
{
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::Depth_Chroma), cu.depth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::QT_Depth_Chroma), cu.qtDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::BT_Depth_Chroma), cu.btDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::MT_Depth_Chroma), cu.mtDepth);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::ChromaQPAdj_Chroma), cu.chromaQpAdj);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::QP_Chroma), cu.qp);
DTRACE_BLOCK_SCALAR_CHROMA(g_trace_ctx, D_BLOCK_STATISTICS_CODED, cu, GetBlockStatisticName(BlockStatistic::SplitSeries_Chroma), (int)cu.splitSeries);
}
for (const PredictionUnit &pu : CU::traversePUs(cu))
{
switch (pu.cu->predMode)
{
case MODE_INTRA:
if (pu.Y().valid())
{
DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, pu, GetBlockStatisticName(BlockStatistic::Luma_IntraMode), PU::getFinalIntraMode(pu, ChannelType(chType)));
}
if (!(pu.chromaFormat == CHROMA_400 || (pu.cu->isSepTree() && pu.chType == CHANNEL_TYPE_LUMA)))