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

◆ extractH264NalUnits()

fl::vector< fl::u8 > fl::extractH264NalUnits ( fl::span< const fl::u8 > data,
const Mp4TrackInfo & track,
fl::string * error )

Definition at line 283 of file mp4_parser.cpp.hpp.

285 {
286 fl::vector<fl::u8> annexB;
287
288 if (!track.isValid) {
289 if (error) *error = "Invalid track info";
290 return annexB;
291 }
292
293 fl::u8 nalLenSize = track.lengthSizeMinusOne + 1; // typically 4
294
295 // Emit SPS NAL units with Annex B start codes
296 for (const auto& sps : track.sps) {
297 annexB.push_back(0x00);
298 annexB.push_back(0x00);
299 annexB.push_back(0x00);
300 annexB.push_back(0x01);
301 for (fl::size j = 0; j < sps.size(); j++) {
302 annexB.push_back(sps[j]);
303 }
304 }
305
306 // Emit PPS NAL units
307 for (const auto& pps : track.pps) {
308 annexB.push_back(0x00);
309 annexB.push_back(0x00);
310 annexB.push_back(0x00);
311 annexB.push_back(0x01);
312 for (fl::size j = 0; j < pps.size(); j++) {
313 annexB.push_back(pps[j]);
314 }
315 }
316
317 // Find mdat box and convert AVCC NAL units to Annex B
318 fl::size mdatPos = fl::size(-1);
319 {
320 fl::size pos = 0;
321 while (pos + 8 <= data.size()) {
322 bool ok = true;
323 fl::u32 boxSize = readU32BE(data, pos, ok);
324 if (!ok || boxSize < 8) break;
325 if (boxIs(data, pos + 4, "mdat")) {
326 mdatPos = pos;
327 break;
328 }
329 pos += boxSize;
330 }
331 }
332
333 if (mdatPos == fl::size(-1)) {
334 if (error) *error = "No mdat box found";
335 return annexB;
336 }
337
338 bool ok = true;
339 fl::u32 mdatSize = readU32BE(data, mdatPos, ok);
340 if (!ok) {
341 if (error) *error = "Invalid mdat box size";
342 return annexB;
343 }
344
345 fl::size mdatBody = mdatPos + 8;
346 fl::size mdatEnd = mdatPos + mdatSize;
347 if (mdatEnd > data.size()) mdatEnd = data.size();
348
349 fl::size pos = mdatBody;
350 while (pos + nalLenSize <= mdatEnd) {
351 fl::u32 nalLen = 0;
352 for (fl::u8 k = 0; k < nalLenSize; k++) {
353 nalLen = (nalLen << 8) | data[pos + k];
354 }
355 pos += nalLenSize;
356
357 if (pos + nalLen > mdatEnd) break;
358
359 // Emit Annex B start code + NAL data
360 annexB.push_back(0x00);
361 annexB.push_back(0x00);
362 annexB.push_back(0x00);
363 annexB.push_back(0x01);
364 for (fl::u32 j = 0; j < nalLen; j++) {
365 annexB.push_back(data[pos + j]);
366 }
367 pos += nalLen;
368 }
369
370 return annexB;
371}
uint8_t pos
Definition Blur.ino:11
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
void push_back(const T &value) FL_NOEXCEPT
Definition vector.h:624
fl::u32 readU32BE(fl::span< const fl::u8 > data, fl::size offset, bool &ok)
bool boxIs(fl::span< const fl::u8 > data, fl::size offset, const char *type)
unsigned char u8
Definition s16x16x4.h:132
unsigned char u8
Definition stdint.h:131
fl::u8 lengthSizeMinusOne
Definition mp4_parser.h:19
fl::vector< fl::vector< fl::u8 > > pps
Definition mp4_parser.h:21
fl::vector< fl::vector< fl::u8 > > sps
Definition mp4_parser.h:20

References fl::Mp4TrackInfo::isValid, fl::Mp4TrackInfo::lengthSizeMinusOne, pos, fl::Mp4TrackInfo::pps, fl::vector< T >::push_back(), fl::span< T, Extent >::size(), and fl::Mp4TrackInfo::sps.

+ Here is the call graph for this function: