FastLED 3.10.8
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 284 of file mp4_parser.cpp.hpp.

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

References FL_NO_EXCEPT, pos, and fl::vector< T >::push_back().

+ Here is the call graph for this function: