1 // Copyright 2021 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/NalParser.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 enum H264ProfileIDC {
20 kProfileIDCAVLC444 = 44,
21 kProfileIDScalableBaseline = 83,
22 kProfileIDScalableHigh = 86,
23 kProfileIDCHigh = 100,
24 kProfileIDHigh10 = 110,
25 kProfileIDSMultiviewHigh = 118,
26 kProfileIDHigh422 = 122,
27 kProfileIDStereoHigh = 128,
28 kProfileIDHigh444Predictive = 244,
29 };
30
31 constexpr uint32_t kYUV444Idc = 3;
32
33 // Read unsigned int encoded with exponential-golomb.
parseUE(ABitReader * br,uint32_t * val)34 bool parseUE(ABitReader* br, uint32_t* val) {
35 uint32_t numZeroes = 0;
36 uint32_t bit;
37 if (!br->getBitsGraceful(1, &bit)) return false;
38 while (bit == 0) {
39 ++numZeroes;
40 if (!br->getBitsGraceful(1, &bit)) return false;
41 }
42 if (!br->getBitsGraceful(numZeroes, val)) return false;
43 *val += (1u << numZeroes) - 1;
44 return true;
45 }
46
47 // Read signed int encoded with exponential-golomb.
parseSE(ABitReader * br,int32_t * val)48 bool parseSE(ABitReader* br, int32_t* val) {
49 uint32_t codeNum;
50 if (!parseUE(br, &codeNum)) return false;
51 *val = (codeNum & 1) ? (codeNum + 1) >> 1 : -static_cast<int32_t>(codeNum >> 1);
52 return true;
53 }
54
55 // Skip a H.264 sequence scaling list in the specified bitstream.
skipScalingList(ABitReader * br,size_t scalingListSize)56 bool skipScalingList(ABitReader* br, size_t scalingListSize) {
57 size_t nextScale = 8;
58 size_t lastScale = 8;
59 for (size_t j = 0; j < scalingListSize; ++j) {
60 if (nextScale != 0) {
61 int32_t deltaScale;
62 if (!parseSE(br, &deltaScale)) return false; // delta_sl
63 if (deltaScale < -128) {
64 ALOGW("delta scale (%d) is below range, capping to -128", deltaScale);
65 deltaScale = -128;
66 } else if (deltaScale > 127) {
67 ALOGW("delta scale (%d) is above range, capping to 127", deltaScale);
68 deltaScale = 127;
69 }
70 nextScale = (lastScale + (deltaScale + 256)) % 256;
71 }
72 lastScale = (nextScale == 0) ? lastScale : nextScale;
73 }
74 return true;
75 }
76
77 // Skip the H.264 sequence scaling matrix in the specified bitstream.
skipScalingMatrix(ABitReader * br,size_t numScalingLists)78 bool skipScalingMatrix(ABitReader* br, size_t numScalingLists) {
79 for (size_t i = 0; i < numScalingLists; ++i) {
80 uint32_t seq_scaling_list_present_flag;
81 if (!br->getBitsGraceful(1, &seq_scaling_list_present_flag))
82 return false; // seq_scaling_list_present_flag
83 if (seq_scaling_list_present_flag) {
84 if (i < 6) {
85 if (!skipScalingList(br, 16)) return false;
86 } else {
87 if (!skipScalingList(br, 64)) return false;
88 }
89 }
90 }
91 return true;
92 }
93
94 } // namespace
95
NalParser(const uint8_t * data,size_t length)96 NalParser::NalParser(const uint8_t* data, size_t length)
97 : mCurrNalDataPos(data), mDataEnd(data + length) {
98 mNextNalStartCodePos = findNextStartCodePos();
99 }
100
locateNextNal()101 bool NalParser::locateNextNal() {
102 if (mNextNalStartCodePos == mDataEnd) return false;
103 mCurrNalDataPos = mNextNalStartCodePos + kNalStartCodeLength; // skip start code.
104 mNextNalStartCodePos = findNextStartCodePos();
105 return true;
106 }
107
locateSPS()108 bool NalParser::locateSPS() {
109 while (locateNextNal()) {
110 if (length() == 0) continue;
111 if (type() != kSPSType) continue;
112 return true;
113 }
114
115 return false;
116 }
117
data() const118 const uint8_t* NalParser::data() const {
119 return mCurrNalDataPos;
120 }
121
length() const122 size_t NalParser::length() const {
123 if (mNextNalStartCodePos == mDataEnd) return mDataEnd - mCurrNalDataPos;
124 size_t length = mNextNalStartCodePos - mCurrNalDataPos;
125 // The start code could be 3 or 4 bytes, i.e., 0x000001 or 0x00000001.
126 return *(mNextNalStartCodePos - 1) == 0x00 ? length - 1 : length;
127 }
128
type() const129 uint8_t NalParser::type() const {
130 // First byte is forbidden_zero_bit (1) + nal_ref_idc (2) + nal_unit_type (5)
131 constexpr uint8_t kNALTypeMask = 0x1f;
132 return *mCurrNalDataPos & kNALTypeMask;
133 }
134
findNextStartCodePos() const135 const uint8_t* NalParser::findNextStartCodePos() const {
136 return std::search(mCurrNalDataPos, mDataEnd, kNalStartCode,
137 kNalStartCode + kNalStartCodeLength);
138 }
139
findCodedColorAspects(ColorAspects * colorAspects)140 bool NalParser::findCodedColorAspects(ColorAspects* colorAspects) {
141 ALOG_ASSERT(colorAspects);
142 ALOG_ASSERT(type() == kSPSType);
143
144 // Unfortunately we can't directly jump to the Video Usability Information (VUI) parameters that
145 // contain the color aspects. We need to parse the entire SPS header up until the values we
146 // need.
147
148 // Skip first byte containing type.
149 ABitReader br(mCurrNalDataPos + 1, length() - 1);
150
151 uint32_t unused;
152 uint32_t profileIDC;
153 if (!br.getBitsGraceful(8, &profileIDC)) return false; // profile_idc
154 br.skipBits(16); // constraint flags + reserved bits + level_idc
155 parseUE(&br, &unused); // seq_parameter_set_id
156
157 if (profileIDC == kProfileIDCHigh || profileIDC == kProfileIDHigh10 ||
158 profileIDC == kProfileIDHigh422 || profileIDC == kProfileIDHigh444Predictive ||
159 profileIDC == kProfileIDCAVLC444 || profileIDC == kProfileIDScalableBaseline ||
160 profileIDC == kProfileIDScalableHigh || profileIDC == kProfileIDSMultiviewHigh ||
161 profileIDC == kProfileIDStereoHigh) {
162 uint32_t chromaFormatIDC;
163 if (!parseUE(&br, &chromaFormatIDC)) return false;
164 if (chromaFormatIDC == kYUV444Idc) { // chroma_format_idc
165 br.skipBits(1); // separate_colour_plane_flag
166 }
167
168 parseUE(&br, &unused); // bit_depth_luma_minus8
169 parseUE(&br, &unused); // bit_depth_chroma_minus8
170 br.skipBits(1); // lossless_qpprime_y_zero_flag
171
172 uint32_t seqScalingMatrixPresentFlag;
173 if (!br.getBitsGraceful(1, &seqScalingMatrixPresentFlag))
174 return false; // seq_scaling_matrix_present_flag
175 if (seqScalingMatrixPresentFlag) {
176 const size_t numScalingLists = (chromaFormatIDC != kYUV444Idc) ? 8 : 12;
177 if (!skipScalingMatrix(&br, numScalingLists)) return false;
178 }
179 }
180
181 parseUE(&br, &unused); // log2_max_frame_num_minus4
182 uint32_t pictureOrderCountType;
183 if (!parseUE(&br, &pictureOrderCountType)) return false; // pic_order_cnt_type
184 if (pictureOrderCountType == 0) {
185 parseUE(&br, &unused); // log2_max_pic_order_cnt_lsb_minus4
186 } else if (pictureOrderCountType == 1) {
187 br.skipBits(1); // delta_pic_order_always_zero_flag
188 int32_t unused_i;
189 parseSE(&br, &unused_i); // offset_for_non_ref_pic
190 parseSE(&br, &unused_i); // offset_for_top_to_bottom_field
191 uint32_t numReferenceFrames;
192 if (!parseUE(&br, &numReferenceFrames))
193 return false; // num_ref_frames_in_pic_order_cnt_cycle
194 for (uint32_t i = 0; i < numReferenceFrames; ++i) {
195 parseUE(&br, &unused); // offset_for_ref_frame
196 }
197 }
198
199 parseUE(&br, &unused); // num_ref_frames
200 br.skipBits(1); // gaps_in_frame_num_value_allowed_flag
201 parseUE(&br, &unused); // pic_width_in_mbs_minus1
202 parseUE(&br, &unused); // pic_height_in_map_units_minus1
203 uint32_t frameMbsOnlyFlag;
204 if (!br.getBitsGraceful(1, &frameMbsOnlyFlag)) return false; // frame_mbs_only_flag
205 if (!frameMbsOnlyFlag) {
206 br.skipBits(1); // mb_adaptive_frame_field_flag
207 }
208 br.skipBits(1); // direct_8x8_inference_flag
209
210 uint32_t frameCroppingFlag;
211 if (!br.getBitsGraceful(1, &frameCroppingFlag)) return false; // frame_cropping_flag
212 if (frameCroppingFlag) {
213 parseUE(&br, &unused); // frame_cropping_rect_left_offset
214 parseUE(&br, &unused); // frame_cropping_rect_right_offset
215 parseUE(&br, &unused); // frame_cropping_rect_top_offset
216 parseUE(&br, &unused); // frame_cropping_rect_bottom_offset
217 }
218
219 uint32_t vuiParametersPresentFlag;
220 if (!br.getBitsGraceful(1, &vuiParametersPresentFlag))
221 return false; // vui_parameters_present_flag
222 if (vuiParametersPresentFlag) {
223 uint32_t aspectRatioInfoPresentFlag;
224 if (!br.getBitsGraceful(1, &aspectRatioInfoPresentFlag))
225 return false; // VUI aspect_ratio_info_present_flag
226 if (aspectRatioInfoPresentFlag) {
227 uint32_t aspectRatioIdc;
228 if (!br.getBitsGraceful(8, &aspectRatioIdc)) return false; // VUI aspect_ratio_idc
229 if (aspectRatioIdc == 255) { // VUI aspect_ratio_idc == extended sample aspect ratio
230 br.skipBits(32); // VUI sar_width + sar_height
231 }
232 }
233
234 uint32_t overscanInfoPresentFlag;
235 if (!br.getBitsGraceful(1, &overscanInfoPresentFlag))
236 return false; // VUI overscan_info_present_flag
237 if (overscanInfoPresentFlag) {
238 br.skipBits(1); // VUI overscan_appropriate_flag
239 }
240 uint32_t videoSignalTypePresentFlag;
241 if (!br.getBitsGraceful(1, &videoSignalTypePresentFlag))
242 return false; // VUI video_signal_type_present_flag
243 if (videoSignalTypePresentFlag) {
244 br.skipBits(3); // VUI video_format
245 uint32_t videoFullRangeFlag;
246 if (!br.getBitsGraceful(1, &videoFullRangeFlag))
247 return false; // VUI videoFullRangeFlag
248 colorAspects->fullRange = videoFullRangeFlag;
249 uint32_t color_description_present_flag;
250 if (!br.getBitsGraceful(1, &color_description_present_flag))
251 return false; // VUI color_description_present_flag
252 if (color_description_present_flag) {
253 if (!br.getBitsGraceful(8, &colorAspects->primaries))
254 return false; // VUI colour_primaries
255 if (!br.getBitsGraceful(8, &colorAspects->transfer))
256 return false; // VUI transfer_characteristics
257 if (!br.getBitsGraceful(8, &colorAspects->coeffs))
258 return false; // VUI matrix_coefficients
259 return true;
260 }
261 }
262 }
263
264 return false; // The NAL unit doesn't contain color aspects info.
265 }
266
267 } // namespace android
268