FastLED 3.9.15
Loading...
Searching...
No Matches

◆ parseSPS()

H264Info fl::H264::parseSPS ( fl::span< const fl::u8 > spsData,
fl::string * error_message = nullptr )
static

Definition at line 85 of file h264.cpp.hpp.

85 {
86 H264Info info;
87
88 if (spsData.size() < 4) {
89 if (error_message) *error_message = "SPS data too small";
90 return info;
91 }
92
93 BitReader br(spsData);
94
95 // NAL unit header: forbidden_zero_bit(1) + nal_ref_idc(2) + nal_unit_type(5)
96 fl::u8 nalHeader = (fl::u8)br.readBits(8);
97 fl::u8 nalType = nalHeader & 0x1F;
98 FL_UNUSED(nalType); // should be 7 for SPS
99
100 // SPS header
101 fl::u8 profile_idc = (fl::u8)br.readBits(8);
102 br.readBits(8); // constraint_set flags + reserved
103 fl::u8 level_idc = (fl::u8)br.readBits(8);
104 br.readUE(); // seq_parameter_set_id
105
106 info.profile = profile_idc;
107 info.level = level_idc;
108
109 // High profile extensions
110 fl::u32 chromaFormatIdc = 1; // default
111 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
112 profile_idc == 244 || profile_idc == 44 || profile_idc == 83 ||
113 profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ||
114 profile_idc == 138 || profile_idc == 139 || profile_idc == 134 ||
115 profile_idc == 135) {
116 chromaFormatIdc = br.readUE();
117 if (chromaFormatIdc == 3) {
118 br.readBits(1); // separate_colour_plane_flag
119 }
120 br.readUE(); // bit_depth_luma_minus8
121 br.readUE(); // bit_depth_chroma_minus8
122 br.readBits(1); // qpprime_y_zero_transform_bypass_flag
123
124 fl::u32 seqScalingMatrixPresent = br.readBits(1);
125 if (seqScalingMatrixPresent) {
126 int limit = (chromaFormatIdc != 3) ? 8 : 12;
127 for (int i = 0; i < limit; i++) {
128 if (br.readBits(1)) { // seq_scaling_list_present_flag
129 skipScalingList(br, (i < 6) ? 16 : 64);
130 }
131 }
132 }
133 }
134
135 br.readUE(); // log2_max_frame_num_minus4
136 fl::u32 picOrderCntType = br.readUE();
137 if (picOrderCntType == 0) {
138 br.readUE(); // log2_max_pic_order_cnt_lsb_minus4
139 } else if (picOrderCntType == 1) {
140 br.readBits(1); // delta_pic_order_always_zero_flag
141 br.readSE(); // offset_for_non_ref_pic
142 br.readSE(); // offset_for_top_to_bottom_field
143 fl::u32 numRefFramesInPoc = br.readUE();
144 for (fl::u32 i = 0; i < numRefFramesInPoc; i++) {
145 br.readSE(); // offset_for_ref_frame
146 }
147 }
148
149 info.numRefFrames = (fl::u8)br.readUE(); // max_num_ref_frames
150 br.readBits(1); // gaps_in_frame_num_value_allowed_flag
151
152 fl::u32 picWidthInMbs = br.readUE() + 1;
153 fl::u32 picHeightInMapUnits = br.readUE() + 1;
154
155 fl::u32 frameMbsOnly = br.readBits(1);
156 if (!frameMbsOnly) {
157 br.readBits(1); // mb_adaptive_frame_field_flag
158 }
159
160 br.readBits(1); // direct_8x8_inference_flag
161
162 // Frame cropping
163 fl::u32 cropLeft = 0, cropRight = 0, cropTop = 0, cropBottom = 0;
164 fl::u32 frameCropping = br.readBits(1);
165 if (frameCropping) {
166 cropLeft = br.readUE();
167 cropRight = br.readUE();
168 cropTop = br.readUE();
169 cropBottom = br.readUE();
170 }
171
172 // Calculate dimensions
173 fl::u32 width = picWidthInMbs * 16;
174 fl::u32 height = (2 - frameMbsOnly) * picHeightInMapUnits * 16;
175
176 // Apply cropping
177 fl::u32 cropUnitX = 1, cropUnitY = 2 - frameMbsOnly;
178 if (chromaFormatIdc == 1) {
179 cropUnitX = 2;
180 cropUnitY *= 2;
181 } else if (chromaFormatIdc == 2) {
182 cropUnitX = 2;
183 cropUnitY *= 1;
184 }
185
186 width -= (cropLeft + cropRight) * cropUnitX;
187 height -= (cropTop + cropBottom) * cropUnitY;
188
189 info.width = (fl::u16)width;
190 info.height = (fl::u16)height;
191 info.isValid = true;
192
193 return info;
194}
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
void skipScalingList(BitReader &br, int size)
Definition h264.cpp.hpp:71
unsigned char u8
Definition s16x16x4.h:132
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
#define FL_UNUSED(x)

References FL_UNUSED, fl::H264Info::height, fl::height, fl::H264Info::isValid, fl::H264Info::level, fl::H264Info::numRefFrames, fl::H264Info::profile, fl::span< T, Extent >::size(), fl::H264Info::width, and fl::width.

Referenced by parseH264Info().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: