• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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