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
97 fl::u8 nalType = nalHeader & 0x1F;
99
100
102 br.readBits(8);
104 br.readUE();
105
106 info.profile = profile_idc;
107 info.level = level_idc;
108
109
110 fl::u32 chromaFormatIdc = 1;
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);
119 }
120 br.readUE();
121 br.readUE();
122 br.readBits(1);
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)) {
130 }
131 }
132 }
133 }
134
135 br.readUE();
136 fl::u32 picOrderCntType = br.readUE();
137 if (picOrderCntType == 0) {
138 br.readUE();
139 } else if (picOrderCntType == 1) {
140 br.readBits(1);
141 br.readSE();
142 br.readSE();
143 fl::u32 numRefFramesInPoc = br.readUE();
144 for (fl::u32 i = 0; i < numRefFramesInPoc; i++) {
145 br.readSE();
146 }
147 }
148
149 info.numRefFrames = (
fl::u8)br.readUE();
150 br.readBits(1);
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);
158 }
159
160 br.readBits(1);
161
162
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
173 fl::u32
width = picWidthInMbs * 16;
174 fl::u32
height = (2 - frameMbsOnly) * picHeightInMapUnits * 16;
175
176
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
void skipScalingList(BitReader &br, int size)