xref: /aosp_15_r20/external/v4l2_codec2/common/HEVCNalParser.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2022 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "NalParser"
7 
8 #include <v4l2_codec2/common/HEVCNalParser.h>
9 
10 #include <algorithm>
11 
12 #include <media/stagefright/foundation/ABitReader.h>
13 #include <utils/Log.h>
14 
15 namespace android {
16 
17 namespace {
18 
19 constexpr uint32_t kMaxShortTermRefPicSets = 64;
20 
21 struct StRefPicSet {
22     // Syntax elements.
23     int numNegativePics;
24     int numPositivePics;
25     int deltaPocS0[kMaxShortTermRefPicSets];
26     int deltaPocS1[kMaxShortTermRefPicSets];
27 
28     // Calculated fields.
29     int numDeltaPocs;
30 };
31 
32 // Skip an HEVC ProfileTierLevel in the specified bitstream.
skipProfileTierLevel(ABitReader * br,uint32_t spsMaxSublayersMinus1)33 bool skipProfileTierLevel(ABitReader* br, uint32_t spsMaxSublayersMinus1) {
34     // general_profile_space(2), general_tier_flag(1), general_profile_idc(5),
35     // general_profile_compatibility_flag(32), general_progressive_source_flag(1),
36     // general_interlaced_source_flag(1), general_non_packed_constraint_flag(1),
37     // general_frame_only_constraint_flag(1), compatibility_flags(43), general_inbld_flag(1),
38     // general_level_idc(8)
39     br->skipBits(96);
40     if (spsMaxSublayersMinus1 > 6) return false;
41     uint32_t subLayerProfilePresentFlag[6];
42     uint32_t subLayerLevelPresentFlag[6];
43     for (uint32_t i = 0; i < spsMaxSublayersMinus1; ++i) {
44         if (!br->getBitsGraceful(1, &subLayerProfilePresentFlag[i])) return false;
45         if (!br->getBitsGraceful(1, &subLayerLevelPresentFlag[i])) return false;
46     }
47     if (spsMaxSublayersMinus1 > 0) {
48         br->skipBits(2 * (8 - spsMaxSublayersMinus1));
49     }
50     for (uint32_t i = 0; i < spsMaxSublayersMinus1; ++i) {
51         if (subLayerProfilePresentFlag[i]) {
52             // sub_layer_profile_space(2), sub_layer_tier_flag(1), sub_layer_profile_idc(5),
53             // sub_layer_profile_compatibility_flag(32),  sub_layer_progressive_source_flag(1),
54             // sub_layer_interlaced_source_flag(1), sub_layer_non_packed_constraint_flag(1),
55             // sub_layer_frame_only_constraint_flag(1), compatibility_flags(43),
56             // sub_layer_inbld_flag(1)
57             br->skipBits(88);
58         }
59         if (subLayerLevelPresentFlag[i]) {
60             br->skipBits(8);  // sub_layer_level_idc
61         }
62     }
63     return true;
64 }
65 
66 // Skip an HEVC ScalingListData in the specified bitstream.
skipScalingListData(ABitReader * br)67 bool skipScalingListData(ABitReader* br) {
68     for (int sizeId = 0; sizeId < 4; ++sizeId) {
69         for (int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
70             uint32_t scalingListPredModeFlag;
71             if (!br->getBitsGraceful(1, &scalingListPredModeFlag)) return false;
72             if (!scalingListPredModeFlag) {
73                 uint32_t unused;
74                 NalParser::parseUE(br, &unused);  // scaling_list_pred_matrix_id_delta
75             } else {
76                 int32_t unused;
77                 if (sizeId > 1)
78                     NalParser::parseSE(br, &unused);  // scaling_list_dc_coef_16x16 or 32x32
79                 int coefNum = std::min(64, (1 << (4 + (sizeId << 1))));
80                 for (int i = 0; i < coefNum; ++i)
81                     NalParser::parseSE(br, &unused);  // scaling_list_delta_coef
82             }
83         }
84     }
85     return true;
86 }
87 
88 // Skip an HEVC StRefPicSet in the specified bitstream.
skipStRefPicSet(ABitReader * br,uint32_t stRpsIdx,uint32_t numShortTermRefPicSets,StRefPicSet * allRefPicSets,StRefPicSet * currRefPicSet)89 bool skipStRefPicSet(ABitReader* br, uint32_t stRpsIdx, uint32_t numShortTermRefPicSets,
90                      StRefPicSet* allRefPicSets, StRefPicSet* currRefPicSet) {
91     uint32_t interRefPicSetPredictionFlag = 0;
92     if (stRpsIdx != 0) {
93         if (!br->getBitsGraceful(1, &interRefPicSetPredictionFlag)) return false;
94     }
95     if (interRefPicSetPredictionFlag) {
96         uint32_t deltaIdxMinus1 = 0;
97         if (stRpsIdx == numShortTermRefPicSets) {
98             if (!NalParser::parseUE(br, &deltaIdxMinus1)) return false;
99             if (deltaIdxMinus1 + 1 > stRpsIdx) {
100                 ALOGW("deltaIdxMinus1 is out of range");
101                 return false;
102             }
103         }
104         int refRpsIdx = stRpsIdx - (static_cast<int>(deltaIdxMinus1) + 1);
105         uint32_t deltaRpsSign;
106         uint32_t absDeltaRpsMinus1;
107         if (!br->getBitsGraceful(1, &deltaRpsSign)) return false;
108         if (!NalParser::parseUE(br, &absDeltaRpsMinus1)) return false;
109         int deltaRps = (1 - 2 * static_cast<int>(deltaRpsSign)) *
110                        (static_cast<int>(absDeltaRpsMinus1) + 1);
111         const StRefPicSet& refSet = allRefPicSets[refRpsIdx];
112         uint32_t useDeltaFlag[kMaxShortTermRefPicSets];
113         // useDeltaFlag defaults to 1 if not present.
114         std::fill_n(useDeltaFlag, kMaxShortTermRefPicSets, 1);
115 
116         for (int j = 0; j <= refSet.numDeltaPocs; j++) {
117             uint32_t usedByCurrPicFlag;
118             if (!br->getBitsGraceful(1, &usedByCurrPicFlag)) return false;
119             if (!usedByCurrPicFlag)
120                 if (!br->getBitsGraceful(1, &useDeltaFlag[j])) return false;
121         }
122         int i = 0;
123         for (int j = refSet.numPositivePics - 1; j >= 0; --j) {
124             int dPoc = refSet.deltaPocS1[j] + deltaRps;
125             if (dPoc < 0 && useDeltaFlag[refSet.numNegativePics + j])
126                 currRefPicSet->deltaPocS0[i++] = dPoc;
127         }
128         if (deltaRps < 0 && useDeltaFlag[refSet.numDeltaPocs]) {
129             currRefPicSet->deltaPocS0[i++] = deltaRps;
130         }
131         for (int j = 0; j < refSet.numNegativePics; ++j) {
132             int dPoc = refSet.deltaPocS0[j] + deltaRps;
133             if (dPoc < 0 && useDeltaFlag[j]) currRefPicSet->deltaPocS0[i++] = dPoc;
134         }
135         currRefPicSet->numNegativePics = i;
136         i = 0;
137         for (int j = refSet.numNegativePics - 1; j >= 0; --j) {
138             int dPoc = refSet.deltaPocS0[j] + deltaRps;
139             if (dPoc > 0 && useDeltaFlag[j]) currRefPicSet->deltaPocS1[i++] = dPoc;
140         }
141         if (deltaRps > 0 && useDeltaFlag[refSet.numDeltaPocs])
142             currRefPicSet->deltaPocS1[i++] = deltaRps;
143         for (int j = 0; j < refSet.numPositivePics; ++j) {
144             int dPoc = refSet.deltaPocS1[j] + deltaRps;
145             if (dPoc > 0 && useDeltaFlag[refSet.numNegativePics + j])
146                 currRefPicSet->deltaPocS1[i++] = dPoc;
147         }
148         currRefPicSet->numPositivePics = i;
149     } else {
150         uint32_t uintForRead;
151         if (!NalParser::parseUE(br, &uintForRead)) return false;
152         currRefPicSet->numNegativePics = static_cast<int>(uintForRead);
153         if (!NalParser::parseUE(br, &uintForRead)) return false;
154         currRefPicSet->numPositivePics = static_cast<int>(uintForRead);
155         if (currRefPicSet->numNegativePics > kMaxShortTermRefPicSets ||
156             currRefPicSet->numPositivePics > kMaxShortTermRefPicSets) {
157             ALOGW("num_negative_pics or num_positive_pics is out of range");
158             return false;
159         }
160         for (int i = 0; i < currRefPicSet->numNegativePics; ++i) {
161             uint32_t deltaPocS0Minus1;
162             if (!NalParser::parseUE(br, &deltaPocS0Minus1)) return false;
163             if (i == 0) {
164                 currRefPicSet->deltaPocS0[i] = -(static_cast<int>(deltaPocS0Minus1) + 1);
165             } else {
166                 currRefPicSet->deltaPocS0[i] =
167                         currRefPicSet->deltaPocS0[i - 1] - (static_cast<int>(deltaPocS0Minus1) + 1);
168             }
169             br->skipBits(1);  // used_by_curr_pic_s0
170         }
171         for (int i = 0; i < currRefPicSet->numPositivePics; ++i) {
172             uint32_t deltaPocS1Minus1;
173             if (!NalParser::parseUE(br, &deltaPocS1Minus1)) return false;
174             if (i == 0) {
175                 currRefPicSet->deltaPocS1[i] = static_cast<int>(deltaPocS1Minus1) + 1;
176             } else {
177                 currRefPicSet->deltaPocS1[i] =
178                         currRefPicSet->deltaPocS1[i - 1] + static_cast<int>(deltaPocS1Minus1) + 1;
179             }
180             br->skipBits(1);  // used_by_curr_pic_s1
181         }
182     }
183     currRefPicSet->numDeltaPocs = currRefPicSet->numNegativePics + currRefPicSet->numPositivePics;
184     if (currRefPicSet->numDeltaPocs > kMaxShortTermRefPicSets) {
185         ALOGW("numDeltaPocs is out of range");
186         return false;
187     }
188     return true;
189 }
190 
191 }  // namespace
192 
HEVCNalParser(const uint8_t * data,size_t length)193 HEVCNalParser::HEVCNalParser(const uint8_t* data, size_t length) : NalParser(data, length) {}
194 
locateSPS()195 bool HEVCNalParser::locateSPS() {
196     while (locateNextNal()) {
197         if (length() == 0) continue;
198         if (type() != kSPSType) continue;
199         return true;
200     }
201 
202     return false;
203 }
204 
locateIDR()205 bool HEVCNalParser::locateIDR() {
206     while (locateNextNal()) {
207         if (length() == 0) continue;
208         if (type() != kIDRType) continue;
209         return true;
210     }
211 
212     return false;
213 }
214 
type() const215 uint8_t HEVCNalParser::type() const {
216     // First bit is forbidden_zero_bit, next 6 are nal_unit_type
217     constexpr uint8_t kNALTypeMask = 0x7e;
218     return (*mCurrNalDataPos & kNALTypeMask) >> 1;
219 }
220 
findCodedColorAspects(ColorAspects * colorAspects)221 bool HEVCNalParser::findCodedColorAspects(ColorAspects* colorAspects) {
222     ALOG_ASSERT(colorAspects);
223     ALOG_ASSERT(type() == kSPSType);
224 
225     // Unfortunately we can't directly jump to the Video Usability Information (VUI) parameters that
226     // contain the color aspects. We need to parse the entire SPS header up until the values we
227     // need.
228     // Skip first 2 bytes for the NALU header.
229     if (length() <= 2) return false;
230     NALBitReader br(mCurrNalDataPos + 2, length() - 2);
231 
232     br.skipBits(4);  // sps_video_parameter_set_id
233     uint32_t spsMaxSublayersMinus1;
234     if (!br.getBitsGraceful(3, &spsMaxSublayersMinus1)) return false;
235     br.skipBits(1);  // sps_temporal_id_nesting_flag
236 
237     if (!skipProfileTierLevel(&br, spsMaxSublayersMinus1)) return false;
238 
239     uint32_t unused;
240     parseUE(&br, &unused);  // sps_seq_parameter_set_id
241     uint32_t chromaFormatIdc;
242     if (!parseUE(&br, &chromaFormatIdc)) return false;
243     if (chromaFormatIdc == 3) br.skipBits(1);  // separate_colour_plane_flag
244     parseUE(&br, &unused);                     // pic_width_in_luma_samples
245     parseUE(&br, &unused);                     // pic_height_in_luma_samples
246 
247     uint32_t conformanceWindowFlag;
248     if (!br.getBitsGraceful(1, &conformanceWindowFlag)) return false;
249     if (conformanceWindowFlag) {
250         parseUE(&br, &unused);  // conf_win_left_offset
251         parseUE(&br, &unused);  // conf_win_right_offset
252         parseUE(&br, &unused);  // conf_win_top_offset
253         parseUE(&br, &unused);  // conf_win_bottom_offset
254     }
255     parseUE(&br, &unused);  // bit_depth_luma_minus8
256     parseUE(&br, &unused);  // bit_depth_chroma_minus8
257     uint32_t log2MaxPicOrderCntLsbMinus4;
258     if (!parseUE(&br, &log2MaxPicOrderCntLsbMinus4)) return false;
259 
260     uint32_t spsSubLayerOrderingInfoPresentFlag;
261     if (!br.getBitsGraceful(1, &spsSubLayerOrderingInfoPresentFlag)) return false;
262     for (uint32_t i = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSublayersMinus1;
263          i <= spsMaxSublayersMinus1; ++i) {
264         parseUE(&br, &unused);  // sps_max_dec_pic_buffering_minus1
265         parseUE(&br, &unused);  // sps_max_num_reorder_pics
266         parseUE(&br, &unused);  // sps_max_latency_increase_plus1
267     }
268     parseUE(&br, &unused);  // log2_min_luma_coding_block_size_minus3
269     parseUE(&br, &unused);  // log2_diff_max_min_luma_coding_block_size
270     parseUE(&br, &unused);  // log2_min_luma_transform_block_size_minus2
271     parseUE(&br, &unused);  // log2_diff_max_min_luma_transform_block_size
272     parseUE(&br, &unused);  // max_transform_hierarchy_depth_inter
273     parseUE(&br, &unused);  // max_transform_hierarchy_depth_intra
274     uint32_t scalingListEnabledFlag;
275     if (!br.getBitsGraceful(1, &scalingListEnabledFlag)) return false;
276     if (scalingListEnabledFlag) {
277         uint32_t spsScalingListDataPresentFlag;
278         if (!br.getBitsGraceful(1, &spsScalingListDataPresentFlag)) return false;
279         if (spsScalingListDataPresentFlag) {
280             if (!skipScalingListData(&br)) return false;
281         }
282     }
283 
284     br.skipBits(2);  // amp_enabled_flag(1), sample_adaptive_offset_enabled_flag(1)
285     uint32_t pcmEnabledFlag;
286     if (!br.getBitsGraceful(1, &pcmEnabledFlag)) return false;
287     if (pcmEnabledFlag) {
288         // pcm_sample_bit_depth_luma_minus1(4), pcm_sample_bit_depth_chroma_minus1(4)
289         br.skipBits(8);
290         parseUE(&br, &unused);  // log2_min_pcm_luma_coding_block_size_minus3
291         parseUE(&br, &unused);  // log2_diff_max_min_pcm_luma_coding_block_size
292         br.skipBits(1);         // pcm_loop_filter_disabled_flag
293     }
294 
295     uint32_t numShortTermRefPicSets;
296     if (!parseUE(&br, &numShortTermRefPicSets)) return false;
297     if (numShortTermRefPicSets > kMaxShortTermRefPicSets) {
298         ALOGW("numShortTermRefPicSets out of range");
299         return false;
300     }
301     StRefPicSet allRefPicSets[kMaxShortTermRefPicSets];
302     memset(allRefPicSets, 0, sizeof(StRefPicSet) * kMaxShortTermRefPicSets);
303     for (uint32_t i = 0; i < numShortTermRefPicSets; ++i) {
304         if (!skipStRefPicSet(&br, i, numShortTermRefPicSets, allRefPicSets, &allRefPicSets[i]))
305             return false;
306     }
307 
308     uint32_t longTermRefPicsPresentFlag;
309     if (!br.getBitsGraceful(1, &longTermRefPicsPresentFlag)) return false;
310     if (longTermRefPicsPresentFlag) {
311         uint32_t numLongTermRefPicsSps;
312         if (!parseUE(&br, &numLongTermRefPicsSps)) return false;
313         for (uint32_t i = 0; i < numLongTermRefPicsSps; ++i) {
314             // lt_ref_pic_poc_lsb_sps
315             if (!br.getBitsGraceful(log2MaxPicOrderCntLsbMinus4 + 4, &unused)) return false;
316             if (!br.getBitsGraceful(1, &unused)) return false;  // used_by_curr_pic_lt_sps_flag
317         }
318     }
319     // sps_temporal_mvp_enabled_flag(1), strong_intra_smoothing_enabled_flag(1)
320     br.skipBits(2);
321     uint32_t vuiParametersPresentFlag;
322     if (!br.getBitsGraceful(1, &vuiParametersPresentFlag)) return false;
323     if (vuiParametersPresentFlag) {
324         uint32_t aspectRatioInfoPresentFlag;
325         if (!br.getBitsGraceful(1, &aspectRatioInfoPresentFlag))
326             return false;  // VUI aspect_ratio_info_present_flag
327         if (aspectRatioInfoPresentFlag) {
328             uint32_t aspectRatioIdc;
329             if (!br.getBitsGraceful(8, &aspectRatioIdc)) return false;  // VUI aspect_ratio_idc
330             if (aspectRatioIdc == 255) {  // VUI aspect_ratio_idc == extended sample aspect ratio
331                 br.skipBits(32);          // VUI sar_width + sar_height
332             }
333         }
334 
335         uint32_t overscanInfoPresentFlag;
336         if (!br.getBitsGraceful(1, &overscanInfoPresentFlag))
337             return false;                             // VUI overscan_info_present_flag
338         if (overscanInfoPresentFlag) br.skipBits(1);  // VUI overscan_appropriate_flag
339         uint32_t videoSignalTypePresentFlag;
340         if (!br.getBitsGraceful(1, &videoSignalTypePresentFlag))
341             return false;  // VUI video_signal_type_present_flag
342         if (videoSignalTypePresentFlag) {
343             br.skipBits(3);  // VUI video_format
344             uint32_t videoFullRangeFlag;
345             if (!br.getBitsGraceful(1, &videoFullRangeFlag))
346                 return false;  // VUI videoFullRangeFlag
347             colorAspects->fullRange = videoFullRangeFlag;
348             uint32_t color_description_present_flag;
349             if (!br.getBitsGraceful(1, &color_description_present_flag))
350                 return false;  // VUI color_description_present_flag
351             if (color_description_present_flag) {
352                 if (!br.getBitsGraceful(8, &colorAspects->primaries))
353                     return false;  // VUI colour_primaries
354                 if (!br.getBitsGraceful(8, &colorAspects->transfer))
355                     return false;  // VUI transfer_characteristics
356                 if (!br.getBitsGraceful(8, &colorAspects->coeffs))
357                     return false;  // VUI matrix_coefficients
358                 return true;
359             }
360         }
361     }
362 
363     return false;  // The NAL unit doesn't contain color aspects info.
364 }
365 
366 }  // namespace android
367