arduino-audio-tools
Loading...
Searching...
No Matches
M4ACommonDemuxer.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <functional>
5#include <string>
6
9#include "MP4Parser.h"
10
11namespace audio_tools {
12
19using stsz_sample_size_t = uint16_t;
20
26 public:
27 enum class Codec { Unknown, AAC, ALAC, MP3, AC3 };
28
29 struct Frame {
31 const char* mime = nullptr;
32 const uint8_t* data;
33 size_t size;
34 };
35
43
49 struct ESDSParser {
53
54 // Parses esds content to extract audioObjectType, frequencyIndex, and
55 // channelConfiguration
56 bool parse(const uint8_t* data, size_t size) {
57 const uint8_t* ptr = data;
58 const uint8_t* end = data + size;
59
60 if (ptr + 4 > end) return false;
61 ptr += 4; // skip version + flags
62
63 if (ptr >= end || *ptr++ != 0x03) return false;
64 size_t es_len = parse_descriptor_length(ptr, end);
65 if (ptr + es_len > end) return false;
66
67 ptr += 2; // skip ES_ID
68 ptr += 1; // skip flags
69
70 if (ptr >= end || *ptr++ != 0x04) return false;
71 size_t dec_len = parse_descriptor_length(ptr, end);
72 if (ptr + dec_len > end) return false;
73
74 ptr += 13; // skip objectTypeIndication, streamType, bufferSizeDB,
75 // maxBitrate, avgBitrate
76
77 if (ptr >= end || *ptr++ != 0x05) return false;
78 size_t dsi_len = parse_descriptor_length(ptr, end);
79 if (ptr + dsi_len > end || dsi_len < 2) return false;
80
81 uint8_t byte1 = ptr[0];
82 uint8_t byte2 = ptr[1];
83
84 audioObjectType = (byte1 >> 3) & 0x1F;
85 samplingRateIndex = ((byte1 & 0x07) << 1) | ((byte2 >> 7) & 0x01);
86 channelConfiguration = (byte2 >> 3) & 0x0F;
87 return true;
88 }
89
90 protected:
91 // Helper to decode variable-length descriptor lengths (e.g. 0x80 80 80 05)
92 inline size_t parse_descriptor_length(const uint8_t*& ptr,
93 const uint8_t* end) {
94 size_t len = 0;
95 for (int i = 0; i < 4 && ptr < end; ++i) {
96 uint8_t b = *ptr++;
97 len = (len << 7) | (b & 0x7F);
98 if ((b & 0x80) == 0) break;
99 }
100 return len;
101 }
102 };
103
110 public:
114 using FrameCallback = std::function<void(const Frame&, void*)>;
115
120
124 void begin() {
125 sampleIndex = 0;
126 buffer.clear();
129 buffer.resize(1024);
130 current_size = 0;
131 box_pos = 0;
132 box_size = 0;
133 }
134
140
145 void setReference(void* r) { ref = r; }
146
153 void setMaxSize(size_t size) {
154 box_size = size;
155 }
156
165 size_t write(const uint8_t* data, size_t len, bool is_final) {
166 // Resize buffer to the current sample size
167 size_t currentSize = currentSampleSize();
168 if (currentSize == 0) {
169 LOGE("No sample size defined: e.g. mdat before stsz!");
170 return 0;
171 }
172 resize(currentSize);
173
175 for (int j = 0; j < len; j++) {
176 assert(buffer.write(data[j]));
177 if (buffer.available() >= currentSize) {
178 LOGI("Sample# %zu: size %zu bytes", sampleIndex, currentSize);
179 executeCallback(currentSize);
180 buffer.clear();
181 box_pos += currentSize;
182 ++sampleIndex;
183 currentSize = currentSampleSize();
184 if (box_pos >= box_size) {
185 LOGI("Reached end of box: %s write",
186 is_final ? "final" : "not final");
187 return j;
188 }
189 if (currentSize == 0) {
190 LOGE("No sample size defined, cannot write data");
191 return j;
192 }
193 // the next sample can be larger than the one we just finished:
194 // grow the buffer for it now, not only once at the top of write()
195 resize(currentSize);
196 }
197 }
198 return len;
199 }
200
208
216
222
230
237 void setFixedSampleCount(uint32_t sampleSize, uint32_t sampleCount) {
238 fixed_sample_size = sampleSize;
239 fixed_sample_count = sampleCount;
240 }
241
249 Frame frame;
250 frame.codec = audio_config.codec;
251 frame.data = buffer.data();
252 frame.size = size;
253 switch (audio_config.codec) {
254 case Codec::AAC: {
255 // Prepare ADTS header + AAC frame
256 tmp.resize(size + 7);
259 size);
260 memcpy(tmp.data() + 7, buffer.data(), size);
261 frame.data = tmp.data();
262 frame.size = size + 7;
263 frame.mime = "audio/aac";
264 break;
265 }
266 case Codec::ALAC:
267 frame.mime = "audio/alac";
268 break;
269 case Codec::MP3:
270 frame.mime = "audio/mpeg";
271 break;
272 case Codec::AC3:
273 frame.mime = "audio/ac3";
274 break;
275 default:
276 frame.mime = nullptr;
277 break;
278 }
279 return frame;
280 }
281
282 protected:
291 void* ref = nullptr;
292 size_t sampleIndex = 0;
294 uint32_t fixed_sample_size = 0;
295 uint32_t fixed_sample_count = 0;
296 size_t current_size = 0;
297 size_t box_size = 0;
298 size_t box_pos = 0;
299
304 void executeCallback(size_t size) {
305 Frame frame = getFrame(size, buffer);
306 if (callback)
307 callback(frame, ref);
308 else
309 LOGE("No callback defined for audio frame extraction");
310 }
311
316 bool resize(size_t newSize) {
317 if (buffer.size() < newSize) {
318 return buffer.resize(newSize);
319 }
320 return true;
321 }
322
328 static size_t last_index = -1;
329 static size_t last_size = -1;
330
331 // Return cached size
332 if (sampleIndex == last_index) {
333 return last_size;
334 }
335
336 // using fixed sizes w/o table
337 if (fixed_sample_size > 0 && fixed_sample_count > 0 &&
339 return fixed_sample_size;
340 }
341 stsz_sample_size_t nextSize = 0;
342 if (p_sample_sizes->read(nextSize)) {
343 last_index = sampleIndex;
344 last_size = nextSize;
345 return nextSize;
346 }
347 return 0;
348 }
349
358 static void writeAdtsHeader(uint8_t* adts, int aacProfile,
359 int sampleRateIdx, int channelCfg,
360 int frameLen) {
361 adts[0] = 0xFF;
362 adts[1] = 0xF1;
363 adts[2] = ((aacProfile - 1) << 6) | (sampleRateIdx << 2) |
364 ((channelCfg >> 2) & 0x1);
365 adts[3] = ((channelCfg & 0x3) << 6) | ((frameLen + 7) >> 11);
366 adts[4] = ((frameLen + 7) >> 3) & 0xFF;
367 adts[5] = (((frameLen + 7) & 0x7) << 5) | 0x1F;
368 adts[6] = 0xFC;
369 }
370 };
371
372 using FrameCallback = std::function<void(const Frame&, void* ref)>;
373
374 M4ACommonDemuxer() = default;
375 virtual ~M4ACommonDemuxer() = default;
376
381 virtual void setCallback(FrameCallback cb) { frame_callback = cb; }
396
413 void setAACConfig(int profile, int srIdx, int chCfg) {
414 audio_config.aacProfile = profile;
416 audio_config.channelCfg = chCfg;
417 }
418
420
422
423 bool resize(size_t size) {
424 default_size = size;
425 if (buffer.size() < size) {
426 return buffer.resize(size);
427 }
428 return true;
429 }
430
432 uint32_t getStszFileOffset() const {
433 return stsz_offset;
434 }
435
437 uint32_t getSampleCount() const {
438 return sample_count;
439 }
440
441 virtual void setupParser() = 0;
442
446
447 protected:
452 bool stsz_processed = false;
453 bool stco_processed = false;
454 bool stsd_processed = false;
457 uint32_t sample_count = 0;
458 uint32_t stsz_offset = 0;
460 size_t default_size = 2 * 1024;
461
467 static uint32_t readU32(const uint8_t* p) {
468 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
469 }
470
471 static uint32_t readU32(const uint32_t num) {
472 uint8_t* p = (uint8_t*)&num;
473 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
474 }
475
476 uint32_t readU32Buffer() {
477 uint32_t nextSize = 0;
478 buffer.readArray((uint8_t*)&nextSize, 4);
479 return readU32(nextSize);
480 }
481
482
490 bool checkType(uint8_t* buffer, const char* type, int offset) {
491 if (buffer == nullptr || type == nullptr) return false;
492 bool result = buffer[offset] == type[0] && buffer[offset + 1] == type[1] &&
493 buffer[offset + 2] == type[2] &&
494 buffer[offset + 3] == type[3];
495 return result;
496 }
497
498 void onStsd(const MP4Parser::Box& box) {
499 LOGI("Box: %s, size: %u bytes", box.type, (unsigned)box.available);
500 if (box.seq == 0) {
501 resize(box.size);
502 buffer.clear();
503 }
504
506
507 if (box.is_complete && buffer.available() >= 8) {
508 // printHexDump(box);
509 uint32_t entryCount = readU32(buffer.data() + 4);
510 // One or more sample entry boxes (e.g. mp4a, .mp3, alac)
511 parser.parseString(buffer.data() + 8, box.data_size - 8,
512 box.file_offset + 8 + 8, box.level + 1);
513 buffer.clear();
514 }
515 }
516
521 void onMp4a(const MP4Parser::Box& box) {
522 LOGI("onMp4a: %s, size: %zu bytes", box.type, box.data_size);
523
524 if (box.is_complete) {
525 // printHexDump(box);
526
527 // use default configuration
528 int aacProfile = 2; // Default: AAC LC
529 int sampleRateIdx = 4; // Default: 44100 Hz
530 int channelCfg = 2; // Default: Stereo
531 setAACConfig(aacProfile, sampleRateIdx, channelCfg);
533
535 int pos = 36 - 8;
536 parser.parseString(box.data + pos, box.data_size - pos, box.level + 1);
537 }
538 }
539
544 void onEsds(const MP4Parser::Box& box) {
545 LOGI("onEsds: %s, size: %zu bytes", box.type, box.data_size);
546 // printHexDump(box);
547 ESDSParser esdsParser;
548 if (!esdsParser.parse(box.data, box.data_size)) {
549 LOGE("Failed to parse esds box");
550 return;
551 }
552 LOGI(
553 "-> esds: AAC objectType: %u, samplingRateIdx: %u, "
554 "channelCfg: %u",
555 esdsParser.audioObjectType, esdsParser.samplingRateIndex,
556 esdsParser.channelConfiguration);
557 setAACConfig(esdsParser.audioObjectType, esdsParser.samplingRateIndex,
558 esdsParser.channelConfiguration);
559 }
560
561 // void fixALACMagicCookie(uint8_t* cookie, size_t len) {
562 // if (len < 28) {
563 // return;
564 // }
565
566 // // Helper to read/write big-endian
567 // auto read32 = [](uint8_t* p) -> uint32_t {
568 // return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
569 // };
570 // auto write32 = [](uint8_t* p, uint32_t val) {
571 // p[0] = (val >> 24) & 0xFF;
572 // p[1] = (val >> 16) & 0xFF;
573 // p[2] = (val >> 8) & 0xFF;
574 // p[3] = val & 0xFF;
575 // };
576 // auto read16 = [](uint8_t* p) -> uint16_t { return (p[0] << 8) | p[1]; };
577 // auto write16 = [](uint8_t* p, uint16_t val) {
578 // p[0] = (val >> 8) & 0xFF;
579 // p[1] = val & 0xFF;
580 // };
581
582 // // Fix values if zero or invalid
583 // if (read32(cookie + 0) == 0) write32(cookie + 0, 4096); // frameLength
584 // if (cookie[6] == 0) cookie[6] = 16; // bitDepth
585 // if (cookie[7] == 0 || cookie[7] > 32) cookie[7] = 10; // pb
586 // if (cookie[8] == 0 || cookie[8] > 32) cookie[8] = 14; // mb
587 // if (cookie[9] == 0 || cookie[9] > 32) cookie[9] = 10; // kb
588 // if (cookie[10] == 0 || cookie[10] > 8) cookie[10] = 2; // numChannels
589 // if (read16(cookie + 11) == 0) write16(cookie + 11, 255); // maxRun
590 // if (read32(cookie + 13) == 0) write32(cookie + 13, 8192); // maxFrameBytes
591 // if (read32(cookie + 17) == 0) write32(cookie + 17, 512000); // avgBitRate
592 // if (read32(cookie + 21) == 0) write32(cookie + 21, 44100); // sampleRate
593 // }
594
599 void onAlac(const MP4Parser::Box& box) {
600 LOGI("onAlac: %s, size: %zu bytes", box.type, box.data_size);
602
603 // only alac box in alac contains magic cookie
604 MP4Parser::Box alac;
605 if (parser.findBox("alac", box.data, box.data_size, alac)) {
606 // fixALACMagicCookie((uint8_t*)alac.data, alac.data_size);
608 std::memcpy(audio_config.alacMagicCookie.data(), alac.data + 4,
609 alac.data_size - 4);
610 }
611 }
612
621 void onAc3(const MP4Parser::Box& box) {
622 LOGI("onAc3: %s, size: %zu bytes", box.type, box.data_size);
624 }
625
632 LOGI("onStsz #%u: %s, size: %u of %u bytes", (unsigned) box.seq, box.type, (unsigned) box.available, (unsigned) box.data_size);
633 if (stsz_processed) return;
634 BaseBuffer<stsz_sample_size_t>& sampleSizes =
636
637 // must fit the leftover bytes from the previous incremental chunk
638 // (not a multiple of 4) plus the new chunk, otherwise writeArray()
639 // silently truncates and corrupts the sample size table
641 size_t written = buffer.writeArray(box.data, box.available);
642 assert(written == (size_t)box.available);
643
644 // get sample count and size from the box
645 if (sample_count == 0 && buffer.available() > 12) {
646 readU32Buffer(); // skip version + flags
647 uint32_t sampleSize = readU32Buffer();
648 uint32_t sampleCount = readU32Buffer();
649 sample_count = sampleCount;
651
652 sampleSizes.resize(sample_count);
653 if (sampleSize != 0) {
654 sampleExtractor.setFixedSampleCount(sampleSize, sampleCount);
655 }
656 }
657
658 // incrementally process sampleSize
659 int count = 0;
660 while (buffer.available() >= 4) {
661 stsz_sample_size_t sampleSize = readU32Buffer();
662 assert(sampleSizes.write(sampleSize));
663 count += 4;
664 }
665 // Remove processed data
666 buffer.trim();
667
668 if (box.is_complete) {
669 stsz_processed = true;
670 }
671 }
672
673 // /**
674 // * @brief Handles the stco (Chunk Offset) box.
675 // * @param box MP4 box.
676 // */
677 // void onStco(MP4Parser::Box& box) {
678 // LOGI("onStco: %s, size: %zu bytes", box.type, box.data_size);
679 // if (stco_processed) return;
680 // BaseBuffer<uint32_t>& chunkOffsets =
681 // sampleExtractor.getChunkOffsetsBuffer();
682
683 // buffer.resize(box.available);
684 // buffer.writeArray(box.data, box.available);
685
686 // // get chunk_offsets_count from the box
687 // if (chunk_offsets_count == 0 && buffer.available() > 12) {
688 // chunk_offsets_count = readU32(buffer.data());
689 // buffer.clearArray(4); // clear version + flags
690 // }
691
692 // // incrementally process sampleSize
693 // int j = 0;
694 // for (j = 0; j < buffer.available(); j += 4) {
695 // uint32_t sampleSize = readU32(buffer.data() + j);
696 // chunkOffsets.write(sampleSize);
697 // }
698 // buffer.clearArray(j);
699
700 // if (box.is_complete) {
701 // stco_processed = true;
702 // }
703 // }
704
705 void printHexDump(const MP4Parser::Box& box) {
706 const uint8_t* data = box.data;
707 size_t len = box.data_size;
708 LOGI("===========================");
709 for (size_t i = 0; i < len; i += 16) {
710 char hex[49] = {0};
711 char ascii[17] = {0};
712 for (size_t j = 0; j < 16 && i + j < len; ++j) {
713 sprintf(hex + j * 3, "%02X ", data[i + j]);
714 ascii[j] = (data[i + j] >= 32 && data[i + j] < 127) ? data[i + j] : '.';
715 }
716 ascii[16] = 0;
717 LOGI("%04zx: %-48s |%s|", i, hex, ascii);
718 }
719 LOGI("===========================");
720 }
721};
722
723} // namespace audio_tools
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define assert(T)
Definition avr.h:10
Shared functionality of all buffers.
Definition Buffers.h:23
virtual bool read(T &result)=0
reads a single value
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:34
virtual bool resize(size_t bytes)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:127
void clear()
same as reset
Definition Buffers.h:96
virtual bool write(T data)=0
write add an entry to the buffer
Extracts audio data based on the sample sizes defined in the stsz box. It collects the data from the ...
Definition M4ACommonDemuxer.h:109
size_t write(const uint8_t *data, size_t len, bool is_final)
Writes data to the extractor, extracting frames as sample sizes are met. Provides the data via the ca...
Definition M4ACommonDemuxer.h:165
void setFixedSampleCount(uint32_t sampleSize, uint32_t sampleCount)
Sets a fixed sample size/count instead of using the sampleSizes table.
Definition M4ACommonDemuxer.h:237
void * ref
Reference pointer for callback.
Definition M4ACommonDemuxer.h:291
BaseBuffer< stsz_sample_size_t > * p_sample_sizes
Definition M4ACommonDemuxer.h:287
FrameCallback callback
Frame callback.
Definition M4ACommonDemuxer.h:290
BaseBuffer< uint32_t > * p_chunk_offsets
Definition M4ACommonDemuxer.h:288
void executeCallback(size_t size)
Executes the callback for a completed frame.
Definition M4ACommonDemuxer.h:304
bool resize(size_t newSize)
Resizes the internal buffer if needed.
Definition M4ACommonDemuxer.h:316
void setSampleSizesBuffer(BaseBuffer< stsz_sample_size_t > &buffer)
Sets the buffer to use for sample sizes.
Definition M4ACommonDemuxer.h:213
static void writeAdtsHeader(uint8_t *adts, int aacProfile, int sampleRateIdx, int channelCfg, int frameLen)
Writes an ADTS header for an AAC frame.
Definition M4ACommonDemuxer.h:358
size_t currentSampleSize()
Returns the current sample size.
Definition M4ACommonDemuxer.h:327
SampleExtractor(M4AAudioConfig &cfg)
Constructor. Initializes the extractor.
Definition M4ACommonDemuxer.h:119
size_t sampleIndex
Current sample index.
Definition M4ACommonDemuxer.h:292
size_t box_pos
Current position in the box.
Definition M4ACommonDemuxer.h:298
SingleBuffer< uint32_t > defaultChunkOffsets
Table of chunk offsets.
Definition M4ACommonDemuxer.h:286
SingleBuffer< stsz_sample_size_t > defaultSampleSizes
Table of sample sizes.
Definition M4ACommonDemuxer.h:285
BaseBuffer< uint32_t > & getChunkOffsetsBuffer()
Returns the buffer of chunk offsets.
Definition M4ACommonDemuxer.h:221
M4AAudioConfig & audio_config
Definition M4ACommonDemuxer.h:283
size_t current_size
Current sample size.
Definition M4ACommonDemuxer.h:296
SingleBuffer< uint8_t > buffer
Buffer for accumulating sample data.
Definition M4ACommonDemuxer.h:293
void begin()
Resets the extractor state.
Definition M4ACommonDemuxer.h:124
size_t box_size
Maximum size of the current sample.
Definition M4ACommonDemuxer.h:297
BaseBuffer< stsz_sample_size_t > & getSampleSizesBuffer()
Returns the buffer of sample sizes.
Definition M4ACommonDemuxer.h:205
void setCallback(FrameCallback cb)
Sets the callback to be called for each extracted frame.
Definition M4ACommonDemuxer.h:139
Frame getFrame(size_t size, SingleBuffer< uint8_t > &buffer)
Constructs a Frame object for the current codec.
Definition M4ACommonDemuxer.h:248
void setReference(void *r)
Sets a reference pointer passed to the callback.
Definition M4ACommonDemuxer.h:145
uint32_t fixed_sample_size
Fixed sample size (if used).
Definition M4ACommonDemuxer.h:294
void setChunkOffsetsBuffer(BaseBuffer< uint32_t > &buffer)
Sets the buffer to use for chunk offsets.
Definition M4ACommonDemuxer.h:227
std::function< void(const Frame &, void *)> FrameCallback
Definition M4ACommonDemuxer.h:114
uint32_t fixed_sample_count
Fixed sample count (if used).
Definition M4ACommonDemuxer.h:295
void setMaxSize(size_t size)
Sets the maximum box size (e.g., for mdat). This is called before the mdat data is posted....
Definition M4ACommonDemuxer.h:153
Vector< uint8_t > tmp
Definition M4ACommonDemuxer.h:289
Abstract base class for M4A/MP4 demuxers. Provides shared functionality for both file-based and strea...
Definition M4ACommonDemuxer.h:25
bool stsd_processed
Definition M4ACommonDemuxer.h:454
MP4Parser parser
Underlying MP4 parser.
Definition M4ACommonDemuxer.h:451
void setAACConfig(int profile, int srIdx, int chCfg)
Sets the AAC configuration for ADTS header generation.
Definition M4ACommonDemuxer.h:413
uint32_t sample_count
Number of samples in stsz.
Definition M4ACommonDemuxer.h:457
void onEsds(const MP4Parser::Box &box)
Handles the esds (Elementary Stream Descriptor) box.
Definition M4ACommonDemuxer.h:544
void onAc3(const MP4Parser::Box &box)
Handles the ac-3 box (AC-3/Dolby Digital audio sample entry). Unlike AAC/ALAC, AC-3 frames are self-s...
Definition M4ACommonDemuxer.h:621
virtual void setCallback(FrameCallback cb)
Sets the callback for extracted audio frames.
Definition M4ACommonDemuxer.h:381
uint32_t readU32Buffer()
Definition M4ACommonDemuxer.h:476
void onStsd(const MP4Parser::Box &box)
Definition M4ACommonDemuxer.h:498
uint32_t stsz_offset
Definition M4ACommonDemuxer.h:458
SampleExtractor sampleExtractor
Extractor for audio samples.
Definition M4ACommonDemuxer.h:449
void setSampleSizesBuffer(BaseBuffer< stsz_sample_size_t > &buffer)
Sets the buffer to use for sample sizes.
Definition M4ACommonDemuxer.h:386
MP4Parser & getParser()
Definition M4ACommonDemuxer.h:445
uint32_t getSampleCount() const
samples in stsz
Definition M4ACommonDemuxer.h:437
void printHexDump(const MP4Parser::Box &box)
Definition M4ACommonDemuxer.h:705
void onAlac(const MP4Parser::Box &box)
Handles the alac box.
Definition M4ACommonDemuxer.h:599
void onStsz(MP4Parser::Box &box)
Handles the stsz (Sample Size) box.
Definition M4ACommonDemuxer.h:630
void onMp4a(const MP4Parser::Box &box)
Handles the mp4a box.
Definition M4ACommonDemuxer.h:521
static uint32_t readU32(const uint8_t *p)
Reads a 32-bit big-endian unsigned integer from a buffer.
Definition M4ACommonDemuxer.h:467
Codec
Definition M4ACommonDemuxer.h:27
uint32_t chunk_offsets_count
Definition M4ACommonDemuxer.h:459
void setM4AAudioConfig(M4AAudioConfig cfg)
Definition M4ACommonDemuxer.h:419
SingleBuffer< uint8_t > buffer
Buffer for incremental data.
Definition M4ACommonDemuxer.h:456
void begin()
Definition M4ACommonDemuxer.h:397
M4AAudioConfig audio_config
Definition M4ACommonDemuxer.h:455
size_t default_size
Default buffer size.
Definition M4ACommonDemuxer.h:460
static uint32_t readU32(const uint32_t num)
Definition M4ACommonDemuxer.h:471
virtual ~M4ACommonDemuxer()=default
bool stsz_processed
Marks the stsz table as processed.
Definition M4ACommonDemuxer.h:452
bool checkType(uint8_t *buffer, const char *type, int offset)
Checks if the buffer at the given offset matches the specified type.
Definition M4ACommonDemuxer.h:490
uint32_t getStszFileOffset() const
File offset of stsz box.
Definition M4ACommonDemuxer.h:432
bool resize(size_t size)
Definition M4ACommonDemuxer.h:423
std::function< void(const Frame &, void *ref)> FrameCallback
Definition M4ACommonDemuxer.h:372
virtual void setupParser()=0
M4AAudioConfig getM4AAudioConfig()
Definition M4ACommonDemuxer.h:421
void setChunkOffsetsBuffer(BaseBuffer< uint32_t > &buffer)
Sets the buffer to use for sample sizes.
Definition M4ACommonDemuxer.h:393
FrameCallback frame_callback
Definition M4ACommonDemuxer.h:448
bool stco_processed
Marks the stco table as processed.
Definition M4ACommonDemuxer.h:453
MP4Parser is a class that parses MP4 container files and extracts boxes (atoms). It provides a callba...
Definition MP4Parser.h:45
static void defaultCallback(const Box &box, void *ref)
Default callback that prints box information to Serial.
Definition MP4Parser.h:281
int parseString(const uint8_t *str, int len, int fileOffset=0, int level=0)
Trigger separate parsing (and callbacks) on the indicated string.
Definition MP4Parser.h:228
bool begin(uint64_t startFileOffset=0)
Initializes the parser.
Definition MP4Parser.h:129
bool findBox(const char *name, const uint8_t *data, size_t len, Box &result)
find box in box
Definition MP4Parser.h:255
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:194
size_t size() override
Definition Buffers.h:325
void trim()
Moves the unprocessed data to the beginning of the buffer.
Definition Buffers.h:295
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:228
int available() override
provides the number of entries that are available to read
Definition Buffers.h:255
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:223
T * data()
Provides address of actual data.
Definition Buffers.h:306
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:327
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void clear()
Definition Vector.h:176
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
uint16_t stsz_sample_size_t
Sample size type optimized for microcontrollers.
Definition M4ACommonDemuxer.h:19
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
A parser for the ESDS segment to extract the relevant aac information.
Definition M4ACommonDemuxer.h:49
uint8_t audioObjectType
Definition M4ACommonDemuxer.h:50
uint8_t channelConfiguration
Definition M4ACommonDemuxer.h:52
uint8_t samplingRateIndex
Definition M4ACommonDemuxer.h:51
size_t parse_descriptor_length(const uint8_t *&ptr, const uint8_t *end)
Definition M4ACommonDemuxer.h:92
bool parse(const uint8_t *data, size_t size)
Definition M4ACommonDemuxer.h:56
Definition M4ACommonDemuxer.h:29
const uint8_t * data
Definition M4ACommonDemuxer.h:32
size_t size
Definition M4ACommonDemuxer.h:33
Codec codec
Definition M4ACommonDemuxer.h:30
const char * mime
Definition M4ACommonDemuxer.h:31
Definition M4ACommonDemuxer.h:36
Vector< uint8_t > alacMagicCookie
ALAC codec config.
Definition M4ACommonDemuxer.h:41
int channelCfg
AAC config.
Definition M4ACommonDemuxer.h:39
Codec codec
Current codec.
Definition M4ACommonDemuxer.h:37
int aacProfile
Definition M4ACommonDemuxer.h:39
int sampleRateIdx
Definition M4ACommonDemuxer.h:39
Represents an individual box in the MP4 file.
Definition MP4Parser.h:50
const uint8_t * data
Pointer to box payload (not including header)
Definition MP4Parser.h:57
int available
Number of bytes available as data.
Definition MP4Parser.h:64
uint64_t file_offset
File offset where box starts.
Definition MP4Parser.h:63
size_t size
Size of payload including subboxes (not including header)
Definition MP4Parser.h:60
bool is_complete
True if the box data is complete.
Definition MP4Parser.h:65
size_t seq
Sequence number for the box per id.
Definition MP4Parser.h:55
char type[5]
4-character box type (null-terminated)
Definition MP4Parser.h:56
int level
Nesting depth.
Definition MP4Parser.h:62
size_t data_size
Size of payload (not including header)
Definition MP4Parser.h:59