1 | /* The copyright in this software is being made available under the BSD |
---|
2 | * License, included below. This software may be subject to other third party |
---|
3 | * and contributor rights, including patent rights, and no such rights are |
---|
4 | * granted under this license. |
---|
5 | * |
---|
6 | * Copyright (c) 2010-2017, ITU/ISO/IEC |
---|
7 | * All rights reserved. |
---|
8 | * |
---|
9 | * Redistribution and use in source and binary forms, with or without |
---|
10 | * modification, are permitted provided that the following conditions are met: |
---|
11 | * |
---|
12 | * * Redistributions of source code must retain the above copyright notice, |
---|
13 | * this list of conditions and the following disclaimer. |
---|
14 | * * Redistributions in binary form must reproduce the above copyright notice, |
---|
15 | * this list of conditions and the following disclaimer in the documentation |
---|
16 | * and/or other materials provided with the distribution. |
---|
17 | * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may |
---|
18 | * be used to endorse or promote products derived from this software without |
---|
19 | * specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS |
---|
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
---|
31 | * THE POSSIBILITY OF SUCH DAMAGE. |
---|
32 | */ |
---|
33 | |
---|
34 | /** \file TDecConformance.cpp |
---|
35 | \brief Decoder conformance functions |
---|
36 | */ |
---|
37 | |
---|
38 | #include "TDecConformance.h" |
---|
39 | #include "TLibCommon/TComSlice.h" |
---|
40 | #include "TLibCommon/TComPic.h" |
---|
41 | #include "TLibCommon/TComPicSym.h" |
---|
42 | #include "NALread.h" |
---|
43 | #include <math.h> |
---|
44 | |
---|
45 | UInt |
---|
46 | LevelTierFeatures::getMaxPicWidthInLumaSamples() const |
---|
47 | { |
---|
48 | return UInt(sqrt(maxLumaPs*8.0)); |
---|
49 | } |
---|
50 | |
---|
51 | UInt |
---|
52 | LevelTierFeatures::getMaxPicHeightInLumaSamples() const |
---|
53 | { |
---|
54 | return UInt(sqrt(maxLumaPs*8.0)); |
---|
55 | } |
---|
56 | |
---|
57 | UInt |
---|
58 | TDecConformanceCheck::getMinLog2CtbSize(const TComPTL &ptl, |
---|
59 | UInt layerPlus1) |
---|
60 | { |
---|
61 | const ProfileTierLevel *pPTL = (layerPlus1==0) ? ptl.getGeneralPTL() : ptl.getSubLayerPTL(layerPlus1-1); |
---|
62 | return (pPTL->getLevelIdc() < Level::LEVEL5) ? 4 : 5; |
---|
63 | } |
---|
64 | |
---|
65 | |
---|
66 | UInt |
---|
67 | TDecConformanceCheck::getMaxLog2CtbSize(const TComPTL &/*ptl*/, |
---|
68 | UInt /*layerPlus1*/) |
---|
69 | { |
---|
70 | return MAX_CU_DEPTH; |
---|
71 | } |
---|
72 | |
---|
73 | |
---|
74 | TDecConformanceCheck::TDecConformanceCheck() |
---|
75 | #if MCTS_ENC_CHECK |
---|
76 | :m_tmctsCheckEnabled(false) |
---|
77 | #if DECODER_PARTIAL_CONFORMANCE_CHECK |
---|
78 | , m_numberOfSlicesInPicture(0) |
---|
79 | , m_bytesInPicture(0) |
---|
80 | #endif |
---|
81 | #else |
---|
82 | #if DECODER_PARTIAL_CONFORMANCE_CHECK |
---|
83 | : m_numberOfSlicesInPicture(0) |
---|
84 | , m_bytesInPicture(0) |
---|
85 | #endif |
---|
86 | #endif |
---|
87 | { |
---|
88 | } |
---|
89 | |
---|
90 | #if DECODER_PARTIAL_CONFORMANCE_CHECK != 0 |
---|
91 | |
---|
92 | static const UInt64 MAX_CNFUINT64 = std::numeric_limits<UInt64>::max(); |
---|
93 | |
---|
94 | static const LevelTierFeatures mainLevelTierInfo[] = |
---|
95 | { |
---|
96 | { Level::LEVEL1 , 36864, { 350, 0 }, 16, 1, 1, 552960ULL, { 128, 0 }, { 2, 2} }, |
---|
97 | { Level::LEVEL2 , 122880, { 1500, 0 }, 16, 1, 1, 3686400ULL, { 1500, 0 }, { 2, 2} }, |
---|
98 | { Level::LEVEL2_1, 245760, { 3000, 0 }, 20, 1, 1, 7372800ULL, { 3000, 0 }, { 2, 2} }, |
---|
99 | { Level::LEVEL3 , 552960, { 6000, 0 }, 30, 2, 2, 16588800ULL, { 6000, 0 }, { 2, 2} }, |
---|
100 | { Level::LEVEL3_1, 983040, { 10000, 0 }, 40, 3, 3, 33177600ULL, { 10000, 0 }, { 2, 2} }, |
---|
101 | { Level::LEVEL4 , 2228224, { 12000, 30000 }, 75, 5, 5, 66846720ULL, { 12000, 30000 }, { 4, 4} }, |
---|
102 | { Level::LEVEL4_1, 2228224, { 20000, 50000 }, 75, 5, 5, 133693440ULL, { 20000, 50000 }, { 4, 4} }, |
---|
103 | { Level::LEVEL5 , 8912896, { 25000, 100000 }, 200, 11, 10, 267386880ULL, { 25000, 100000 }, { 6, 4} }, |
---|
104 | { Level::LEVEL5_1, 8912896, { 40000, 160000 }, 200, 11, 10, 534773760ULL, { 40000, 160000 }, { 8, 4} }, |
---|
105 | { Level::LEVEL5_2, 8912896, { 60000, 240000 }, 200, 11, 10, 1069547520ULL, { 60000, 240000 }, { 8, 4} }, |
---|
106 | { Level::LEVEL6 , 35651584, { 60000, 240000 }, 600, 22, 20, 1069547520ULL, { 60000, 240000 }, { 8, 4} }, |
---|
107 | { Level::LEVEL6_1, 35651584, { 120000, 480000 }, 600, 22, 20, 2139095040ULL, { 120000, 480000 }, { 8, 4} }, |
---|
108 | { Level::LEVEL6_2, 35651584, { 240000, 800000 }, 600, 22, 20, 4278190080ULL, { 240000, 800000 }, { 6, 4} }, |
---|
109 | { Level::LEVEL8_5, MAX_UINT, { MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} }, |
---|
110 | { Level::NONE } |
---|
111 | }; |
---|
112 | |
---|
113 | static const ProfileFeatures validProfiles[] = |
---|
114 | { // profile, pNameString, maxBitDepth, maxChrFmt, intra, 1pic, lowerBR, RExtTools, ExtPrec , ChrmQPOf, align, HBRFactor, , wve+t, tiles,, lvl8.5, cpbvcl, cpbnal, fcf*1000, mincr*10 |
---|
115 | { Profile::MAIN, "Main", 8, CHROMA_420, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1 , false, 256, 64, false, 1000, 1100, 1500, 10 , mainLevelTierInfo }, |
---|
116 | { Profile::MAIN10, "Main10", 10, CHROMA_420, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1 , false, 256, 64, false, 1000, 1100, 1875, 10 , mainLevelTierInfo }, |
---|
117 | { Profile::MAIN10, "Main10 Still Picture", 10, CHROMA_420, false, true, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1 , false, 256, 64, true , 1000, 1100, 1875, 10 , mainLevelTierInfo }, |
---|
118 | { Profile::MAINSTILLPICTURE, "Main Still Picture", 8, CHROMA_420, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1 , false, 256, 64, true , 1000, 1100, 1500, 10 , mainLevelTierInfo }, |
---|
119 | { Profile::MAINREXT, "Monochrome", 8, CHROMA_400, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 667, 733, 1000, 10 , mainLevelTierInfo }, |
---|
120 | { Profile::MAINREXT, "Monochrome 12", 12, CHROMA_400, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1000, 1100, 1500, 10 , mainLevelTierInfo }, |
---|
121 | { Profile::MAINREXT, "Monochrome 16", 16, CHROMA_400, false, false, ENABLED , OPTIONAL, OPTIONAL, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1333, 1467, 2000, 10 , mainLevelTierInfo }, |
---|
122 | { Profile::MAINREXT, "Main 12", 12, CHROMA_420, false, false, ENABLED , DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1500, 1650, 2250, 10 , mainLevelTierInfo }, |
---|
123 | { Profile::MAINREXT, "Main 4:2:2 10", 10, CHROMA_422, false, false, ENABLED , DISABLED, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1667, 1833, 2500, 5 , mainLevelTierInfo }, |
---|
124 | { Profile::MAINREXT, "Main 4:2:2 12", 12, CHROMA_422, false, false, ENABLED , DISABLED, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2000, 2200, 3000, 5 , mainLevelTierInfo }, |
---|
125 | { Profile::MAINREXT, "Main 4:4:4", 8, CHROMA_444, false, false, ENABLED , OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2000, 2200, 3000, 5 , mainLevelTierInfo }, |
---|
126 | { Profile::MAINREXT, "Main 4:4:4 10", 10, CHROMA_444, false, false, ENABLED , OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2500, 2750, 3750, 5 , mainLevelTierInfo }, |
---|
127 | { Profile::MAINREXT, "Main 4:4:4 12", 12, CHROMA_444, false, false, ENABLED , OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 3000, 3300, 4500, 5 , mainLevelTierInfo }, |
---|
128 | { Profile::MAINREXT, "Main Intra", 8, CHROMA_420, true , false, OPTIONAL, DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1000, 1100, 1500, 10 , mainLevelTierInfo }, |
---|
129 | { Profile::MAINREXT, "Main 10 Intra", 10, CHROMA_420, true , false, OPTIONAL, DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1000, 1100, 1875, 10 , mainLevelTierInfo }, |
---|
130 | { Profile::MAINREXT, "Main 12 Intra", 12, CHROMA_420, true , false, OPTIONAL, DISABLED, DISABLED, DISABLED, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1500, 1650, 2250, 10 , mainLevelTierInfo }, |
---|
131 | { Profile::MAINREXT, "Main 4:2:2 10 Intra", 10, CHROMA_422, true , false, OPTIONAL, DISABLED, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 1667, 1833, 2500, 5 , mainLevelTierInfo }, |
---|
132 | { Profile::MAINREXT, "Main 4:2:2 12 Intra", 12, CHROMA_422, true , false, OPTIONAL, DISABLED, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2000, 2200, 3000, 5 , mainLevelTierInfo }, |
---|
133 | { Profile::MAINREXT, "Main 4:4:4 Intra", 8, CHROMA_444, true , false, OPTIONAL, OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2000, 2200, 3000, 5 , mainLevelTierInfo }, |
---|
134 | { Profile::MAINREXT, "Main 4:4:4 10 Intra", 10, CHROMA_444, true , false, OPTIONAL, OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 2500, 2750, 3750, 5 , mainLevelTierInfo }, |
---|
135 | { Profile::MAINREXT, "Main 4:4:4 12 Intra", 12, CHROMA_444, true , false, OPTIONAL, OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 3000, 3300, 4500, 5 , mainLevelTierInfo }, |
---|
136 | { Profile::MAINREXT, "Main 4:4:4 16 Intra", 16, CHROMA_444, true , false, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, false, 4000, 4400, 6000, 5 , mainLevelTierInfo }, |
---|
137 | { Profile::MAINREXT, "Main 4:4:4 Still Picture", 8, CHROMA_444, true , true , OPTIONAL, OPTIONAL, DISABLED, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, true , 2000, 2200, 3000, 5 , mainLevelTierInfo }, |
---|
138 | { Profile::MAINREXT, "Main 4:4:4 16 Still Picture", 16, CHROMA_444, true , true , OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL, DISABLED, HBR_1_OR_2 , false, 256, 64, true , 4000, 4400, 6000, 5 , mainLevelTierInfo }, |
---|
139 | { Profile::HIGHTHROUGHPUTREXT, "High Throughput 4:4:4 16 Intra", 16, CHROMA_444, true , false, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL, ENABLED , HBR_12_OR_24 , true , 256, 64, false, 4000, 4400, 6000, 5 , mainLevelTierInfo }, |
---|
140 | { Profile::NONE, 0 } |
---|
141 | }; |
---|
142 | |
---|
143 | |
---|
144 | |
---|
145 | |
---|
146 | static Void |
---|
147 | checkSPS(const TComSPS &sps, |
---|
148 | const ProfileLevelTierFeatures &features) |
---|
149 | { |
---|
150 | // sps_max_sub_layers_minus1 shall be less than or equal to vsp_max_sub_layers_minus1 |
---|
151 | |
---|
152 | // TODO - check conformance of sps_max_dec_pic_buffering_minus1, sps_max_num_reorder_pics, sps_max_latency_increase_plus1 |
---|
153 | // needs VPS, which can only be done on activation. |
---|
154 | |
---|
155 | const UInt minCbSizeY = 1<<(sps.getLog2MinCodingBlockSize()); |
---|
156 | |
---|
157 | if (sps.getPicWidthInLumaSamples() % minCbSizeY != 0 ) |
---|
158 | { |
---|
159 | TDecConformanceCheck::getStream() << "picture width (" << sps.getPicWidthInLumaSamples() << ") must be a multiple of minCbSizeY (=" << minCbSizeY << ")\n"; |
---|
160 | TDecConformanceCheck::finishWarningReport(); |
---|
161 | } |
---|
162 | |
---|
163 | if (sps.getPicHeightInLumaSamples() % minCbSizeY != 0 ) |
---|
164 | { |
---|
165 | TDecConformanceCheck::getStream() << "picture height (" << sps.getPicHeightInLumaSamples() << ") must be a multiple of minCbSizeY (=" << minCbSizeY << ")\n"; |
---|
166 | TDecConformanceCheck::finishWarningReport(); |
---|
167 | } |
---|
168 | |
---|
169 | |
---|
170 | if (sps.getPicWidthInLumaSamples() > features.getLevelTierFeatures()->getMaxPicWidthInLumaSamples()) |
---|
171 | { |
---|
172 | TDecConformanceCheck::getStream() << "picture width (" << sps.getPicWidthInLumaSamples() << ") exceeds the maximum allowed by the level (" << features.getLevelTierFeatures()->getMaxPicWidthInLumaSamples() << ")\n"; |
---|
173 | TDecConformanceCheck::finishWarningReport(); |
---|
174 | } |
---|
175 | |
---|
176 | if (sps.getPicHeightInLumaSamples() > features.getLevelTierFeatures()->getMaxPicHeightInLumaSamples()) |
---|
177 | { |
---|
178 | TDecConformanceCheck::getStream() << "picture height (" << sps.getPicHeightInLumaSamples() << ") exceeds the maximum allowed by the level (" << features.getLevelTierFeatures()->getMaxPicHeightInLumaSamples() << ")\n"; |
---|
179 | TDecConformanceCheck::finishWarningReport(); |
---|
180 | } |
---|
181 | |
---|
182 | if (sps.getPicWidthInLumaSamples() * sps.getPicHeightInLumaSamples() > features.getLevelTierFeatures()->maxLumaPs) |
---|
183 | { |
---|
184 | TDecConformanceCheck::getStream() << "picture samples (" << sps.getPicWidthInLumaSamples() << " * " << sps.getPicHeightInLumaSamples() << ") exceeds the maximum allowed by the level (" << features.getLevelTierFeatures()->maxLumaPs << ")\n"; |
---|
185 | TDecConformanceCheck::finishWarningReport(); |
---|
186 | } |
---|
187 | } |
---|
188 | |
---|
189 | |
---|
190 | static Void |
---|
191 | checkTiles(const TComSPS &sps, |
---|
192 | const TComPPS &pps, |
---|
193 | const TComPic &pic, |
---|
194 | const ProfileLevelTierFeatures &features) |
---|
195 | { |
---|
196 | if (pps.getTilesEnabledFlag()) |
---|
197 | { |
---|
198 | // Tile size check |
---|
199 | const Int minWidthInCtus = features.getProfileFeatures()->minTileColumnWidthInLumaSamples/ sps.getMaxCUWidth(); |
---|
200 | const Int minHeightInCtus = features.getProfileFeatures()->minTileRowHeightInLumaSamples / sps.getMaxCUHeight(); |
---|
201 | |
---|
202 | const Int numCols = pps.getNumTileColumnsMinus1() + 1; |
---|
203 | const Int numRows = pps.getNumTileRowsMinus1() + 1; |
---|
204 | if (numCols > features.getLevelTierFeatures()->maxTileCols) |
---|
205 | { |
---|
206 | TDecConformanceCheck::getStream() << "number of tile columns (" << numCols << ") exceeds the maximum allowed by the level (" << features.getLevelTierFeatures()->maxTileCols << ")\n"; |
---|
207 | TDecConformanceCheck::finishWarningReport(); |
---|
208 | } |
---|
209 | if (numRows > features.getLevelTierFeatures()->maxTileRows) |
---|
210 | { |
---|
211 | TDecConformanceCheck::getStream() << "number of tile rows (" << numRows << ") exceeds the maximum allowed by the level (" << features.getLevelTierFeatures()->maxTileRows << ")\n"; |
---|
212 | TDecConformanceCheck::finishWarningReport(); |
---|
213 | } |
---|
214 | |
---|
215 | for(Int row=0; row < numRows; row++) |
---|
216 | { |
---|
217 | for(Int col=0; col < numCols; col++) |
---|
218 | { |
---|
219 | const Int tileIdx = row * numCols + col; |
---|
220 | const TComTile &tile = *(pic.getPicSym()->getTComTile(tileIdx)); |
---|
221 | if (tile.getTileWidthInCtus() < minWidthInCtus) |
---|
222 | { |
---|
223 | TDecConformanceCheck::getStream() << "width of tile (" << col << ", " << row << ") is too narrow for the profile - read " << tile.getTileWidthInCtus()*sps.getMaxCUWidth() << "must be " << minWidthInCtus*sps.getMaxCUWidth() << "\n"; |
---|
224 | TDecConformanceCheck::finishWarningReport(); |
---|
225 | } |
---|
226 | if (tile.getTileHeightInCtus() < minHeightInCtus) |
---|
227 | { |
---|
228 | TDecConformanceCheck::getStream() << "height of tile (" << col << ", " << row << ") is too thin for the profile - read " << tile.getTileHeightInCtus()*sps.getMaxCUHeight() << " must be " << minHeightInCtus*sps.getMaxCUHeight() << "\n"; |
---|
229 | TDecConformanceCheck::finishWarningReport(); |
---|
230 | } |
---|
231 | } |
---|
232 | } |
---|
233 | |
---|
234 | if (pps.getEntropyCodingSyncEnabledFlag() && !features.getProfileFeatures()->bWavefrontsAndTilesCanBeUsedSimultaneously) |
---|
235 | { |
---|
236 | TDecConformanceCheck::getStream() << "profile does not permit entropy coding sync and tiles to be simultaneously enabled\n"; |
---|
237 | TDecConformanceCheck::finishWarningReport(); |
---|
238 | } |
---|
239 | } |
---|
240 | } |
---|
241 | |
---|
242 | |
---|
243 | static Void |
---|
244 | checkPPS(const TComSPS &sps, |
---|
245 | const TComPPS &pps, |
---|
246 | const TComPic &pic, |
---|
247 | const ProfileLevelTierFeatures &features) |
---|
248 | { |
---|
249 | TDecConformanceCheck::checkRange<Int>(pps.getPicInitQPMinus26(), "init_qp_minus26", -(sps.getBitDepth(CHANNEL_TYPE_LUMA)-8)*6-26, 25); |
---|
250 | TDecConformanceCheck::checkRange<UInt>(pps.getMaxCuDQPDepth(), "diff_cu_qp_delta_depth", 0, sps.getLog2DiffMaxMinCodingBlockSize()); |
---|
251 | TDecConformanceCheck::checkRange<UInt>(pps.getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2", 0, sps.getLog2MinCodingBlockSize() + sps.getLog2DiffMaxMinCodingBlockSize() - 2); |
---|
252 | |
---|
253 | TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getLog2SaoOffsetScale(CHANNEL_TYPE_LUMA), "log2_sao_offset_scale_luma", 0, std::max(sps.getBitDepth(CHANNEL_TYPE_LUMA), 10)-10); |
---|
254 | TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA), "log2_sao_offset_scale_chroma", 0, std::max(sps.getBitDepth(CHANNEL_TYPE_CHROMA), 10)-10); |
---|
255 | |
---|
256 | checkTiles(sps, pps, pic, features); |
---|
257 | } |
---|
258 | |
---|
259 | |
---|
260 | Void |
---|
261 | ProfileLevelTierFeatures::activate(const TComSPS &sps) |
---|
262 | { |
---|
263 | const ProfileTierLevel &ptl = *(sps.getPTL()->getGeneralPTL()); |
---|
264 | |
---|
265 | m_tier = ptl.getTierFlag(); |
---|
266 | |
---|
267 | for(Int i=0; validProfiles[i].profile != Profile::NONE; i++) |
---|
268 | { |
---|
269 | if (ptl.getProfileIdc() == validProfiles[i].profile && |
---|
270 | ptl.getBitDepthConstraint() == validProfiles[i].maxBitDepth && |
---|
271 | ptl.getChromaFormatConstraint() == validProfiles[i].maxChromaFormat && |
---|
272 | ptl.getIntraConstraintFlag() == validProfiles[i].generalIntraConstraintFlag && |
---|
273 | ptl.getOnePictureOnlyConstraintFlag() == validProfiles[i].generalOnePictureOnlyConstraintFlag ) |
---|
274 | { |
---|
275 | m_pProfile = &(validProfiles[i]); |
---|
276 | break; |
---|
277 | } |
---|
278 | } |
---|
279 | |
---|
280 | if (m_pProfile != 0) |
---|
281 | { |
---|
282 | // Now identify the level: |
---|
283 | const LevelTierFeatures *pLTF = m_pProfile->pLevelTiersListInfo; |
---|
284 | const Level::Name spsLevelName = sps.getPTL()->getGeneralPTL()->getLevelIdc(); |
---|
285 | if (spsLevelName!=Level::LEVEL8_5 || m_pProfile->bCanUseLevel8p5) |
---|
286 | { |
---|
287 | for(Int i=0; pLTF[i].level!=Level::NONE; i++) |
---|
288 | { |
---|
289 | if (pLTF[i].level == spsLevelName) |
---|
290 | { |
---|
291 | m_pLevelTier = &(pLTF[i]); |
---|
292 | } |
---|
293 | } |
---|
294 | } |
---|
295 | } |
---|
296 | |
---|
297 | { |
---|
298 | const UInt ctbSizeY = sps.getMaxCUWidth(); |
---|
299 | const UInt bitDepthY = sps.getBitDepth(CHANNEL_TYPE_LUMA); |
---|
300 | const UInt ctbWidthC = ctbSizeY >> getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, sps.getChromaFormatIdc()); |
---|
301 | const UInt ctbHeightC = ctbSizeY >> getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, sps.getChromaFormatIdc()); |
---|
302 | const UInt bitDepthC = sps.getBitDepth(CHANNEL_TYPE_LUMA); |
---|
303 | |
---|
304 | const UInt rawCtuBits = ctbSizeY*ctbSizeY*bitDepthY+2*(ctbWidthC*ctbHeightC)*bitDepthC; |
---|
305 | m_maxRawCtuBits=(rawCtuBits*5)/3; |
---|
306 | } |
---|
307 | |
---|
308 | } |
---|
309 | |
---|
310 | |
---|
311 | static Void |
---|
312 | checkToolAvailability(const TComSPS &sps, |
---|
313 | const TComPPS &pps, |
---|
314 | const ProfileLevelTierFeatures &features) |
---|
315 | { |
---|
316 | const TRISTATE rextToolsEnabled = features.getProfileFeatures()->generalRExtToolsEnabled; |
---|
317 | if ( rextToolsEnabled != OPTIONAL) |
---|
318 | { |
---|
319 | const Bool bWantedFlagState = rextToolsEnabled == ENABLED; |
---|
320 | std::string flags; |
---|
321 | if (sps.getSpsRangeExtension().getTransformSkipRotationEnabledFlag() != bWantedFlagState) flags+=", transform_skip_rotation_enabled_flag"; |
---|
322 | if (sps.getSpsRangeExtension().getTransformSkipContextEnabledFlag() != bWantedFlagState) flags+=", transform_skip_context_enabled_flag"; |
---|
323 | if (sps.getSpsRangeExtension().getRdpcmEnabledFlag(RDPCM_SIGNAL_IMPLICIT) != bWantedFlagState) flags+=", implicit_rdpcm_enabled_flag"; |
---|
324 | if (sps.getSpsRangeExtension().getRdpcmEnabledFlag(RDPCM_SIGNAL_EXPLICIT) != bWantedFlagState) flags+=", explicit_rdpcm_enabled_flag"; |
---|
325 | if (sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag() != bWantedFlagState) flags+=", intra_smoothing_disabled_flag"; |
---|
326 | if (sps.getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag() != bWantedFlagState) flags+=", persistent_rice_adaptation_enabled_flag"; |
---|
327 | if (pps.getPpsRangeExtension().getLog2MaxTransformSkipBlockSize() != 2 && rextToolsEnabled==DISABLED ) flags+=", log2_max_transform_skip_block_size_minus2"; |
---|
328 | |
---|
329 | if (!flags.empty()) |
---|
330 | { |
---|
331 | TDecConformanceCheck::getStream() << "the following flags must all be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point: " + flags.substr(2) + "\n"; |
---|
332 | TDecConformanceCheck::finishWarningReport(); |
---|
333 | } |
---|
334 | } |
---|
335 | else |
---|
336 | { |
---|
337 | TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()-2, "log2_max_transform_skip_block_size_minus2", 0, sps.getQuadtreeTULog2MaxSize()-2); |
---|
338 | } |
---|
339 | |
---|
340 | if (features.getProfileFeatures()->extendedPrecisionProcessingFlag != OPTIONAL) |
---|
341 | { |
---|
342 | const Bool bWantedFlagState = features.getProfileFeatures()->extendedPrecisionProcessingFlag == ENABLED; |
---|
343 | if (sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() != bWantedFlagState) |
---|
344 | { |
---|
345 | TDecConformanceCheck::getStream() << "extended_precision_processing_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n"; |
---|
346 | TDecConformanceCheck::finishWarningReport(); |
---|
347 | } |
---|
348 | } |
---|
349 | |
---|
350 | if (features.getProfileFeatures()->chromaQpOffsetListEnabledFlag != OPTIONAL) |
---|
351 | { |
---|
352 | const Bool bWantedFlagState = features.getProfileFeatures()->chromaQpOffsetListEnabledFlag == ENABLED; |
---|
353 | if (pps.getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() != bWantedFlagState) |
---|
354 | { |
---|
355 | TDecConformanceCheck::getStream() << "chroma_qp_offset_list_enabled_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n"; |
---|
356 | TDecConformanceCheck::finishWarningReport(); |
---|
357 | } |
---|
358 | } |
---|
359 | else if (pps.getPpsRangeExtension().getChromaQpOffsetListEnabledFlag()) |
---|
360 | { |
---|
361 | TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getDiffCuChromaQpOffsetDepth(), "diff_cu_chroma_qp_offset_depth", 0, sps.getLog2DiffMaxMinCodingBlockSize()); |
---|
362 | } |
---|
363 | |
---|
364 | if (features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag != OPTIONAL) |
---|
365 | { |
---|
366 | const Bool bWantedFlagState = features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag == ENABLED; |
---|
367 | if (sps.getSpsRangeExtension().getCabacBypassAlignmentEnabledFlag() != bWantedFlagState) |
---|
368 | { |
---|
369 | TDecConformanceCheck::getStream() << "cabac_bypass_alignment_enabled_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n"; |
---|
370 | TDecConformanceCheck::finishWarningReport(); |
---|
371 | } |
---|
372 | } |
---|
373 | } |
---|
374 | |
---|
375 | |
---|
376 | Void |
---|
377 | TDecConformanceCheck::checkSliceActivation(const TComSlice &slice, |
---|
378 | const InputNALUnit &nalu, |
---|
379 | const TComPic &pic, |
---|
380 | const Bool bFirstSliceInStream, |
---|
381 | const Bool bFirstSliceInSequence, |
---|
382 | const Bool bFirstSliceInPicture) |
---|
383 | { |
---|
384 | const TComSPS &sps=*(slice.getSPS()); |
---|
385 | const TComPPS &pps=*(slice.getPPS()); |
---|
386 | |
---|
387 | if (!doChecking()) return; |
---|
388 | |
---|
389 | m_activatedFeatures.activate(sps); |
---|
390 | |
---|
391 | if (m_activatedFeatures.getProfileFeatures() == 0 || m_activatedFeatures.getLevelTierFeatures() == 0) |
---|
392 | { |
---|
393 | if (m_activatedFeatures.getProfileFeatures() == 0) |
---|
394 | { |
---|
395 | getStream() << "Unknown profile/constraint flag combination discovered\n"; |
---|
396 | } |
---|
397 | else |
---|
398 | { |
---|
399 | getStream() << "Unknown level IDC discovered\n"; |
---|
400 | } |
---|
401 | finishWarningReport(); |
---|
402 | } |
---|
403 | else |
---|
404 | { |
---|
405 | // Most of the parameters have been individually checked prior to this as they were decoded. |
---|
406 | checkSPS(sps, m_activatedFeatures); // checks SPS limits |
---|
407 | checkPPS(sps, pps, pic, m_activatedFeatures); // checks PPS limits |
---|
408 | checkToolAvailability(sps, pps, m_activatedFeatures); |
---|
409 | |
---|
410 | if (m_activatedFeatures.getProfileFeatures()->onlyIRAPPictures() && (nalu.m_nalUnitType < NAL_UNIT_CODED_SLICE_BLA_W_LP || nalu.m_nalUnitType> NAL_UNIT_RESERVED_IRAP_VCL23)) |
---|
411 | { |
---|
412 | getStream() << "Bad NALU for an intra constrained profile\n"; |
---|
413 | finishWarningReport(); |
---|
414 | } |
---|
415 | |
---|
416 | if (bFirstSliceInStream || bFirstSliceInSequence || bFirstSliceInPicture) |
---|
417 | { |
---|
418 | m_numberOfSlicesInPicture=1; |
---|
419 | m_bytesInPicture=0; |
---|
420 | } |
---|
421 | else |
---|
422 | { |
---|
423 | m_numberOfSlicesInPicture++; |
---|
424 | if (m_numberOfSlicesInPicture > m_activatedFeatures.getLevelTierFeatures()->maxSliceSegmentsPerPicture) |
---|
425 | { |
---|
426 | getStream() << "Too many slice segments in the picture\n"; |
---|
427 | finishWarningReport(); |
---|
428 | } |
---|
429 | } |
---|
430 | |
---|
431 | // Currently no HRD analysis is made. For now, just ensure access unit fits within the CPB. |
---|
432 | m_bytesInPicture+=nalu.getBitstream().getFifo().size(); |
---|
433 | if (m_bytesInPicture*8 > m_activatedFeatures.getCpbSizeInBits()) |
---|
434 | { |
---|
435 | getStream() << "Entire access unit must fit within the CPB even if split into multiple decoding units (section C.2.2 Timing of decoding unit arrival)\n"; |
---|
436 | finishWarningReport(); |
---|
437 | } |
---|
438 | } |
---|
439 | } |
---|
440 | |
---|
441 | |
---|
442 | Void |
---|
443 | TDecConformanceCheck::checkCtuDecoding(const UInt numUsedBits) |
---|
444 | { |
---|
445 | if (numUsedBits > m_activatedFeatures.getMaxRawCtuBits()) |
---|
446 | { |
---|
447 | getStream() << "CTU exceeds maximum RAW CTU bits limits.\n"; |
---|
448 | finishWarningReport(); |
---|
449 | } |
---|
450 | } |
---|
451 | |
---|
452 | #endif |
---|