Skip to content

Commit 8e5de20

Browse files
committed
M4AAudioDemuxer: cleanup
1 parent 7394a42 commit 8e5de20

File tree

2 files changed

+56
-48
lines changed

2 files changed

+56
-48
lines changed

src/AudioTools/AudioCodecs/M4AAudioDemuxer.h

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class M4AAudioDemuxer {
153153

154154
/**
155155
* @brief Writes data to the extractor, extracting frames as sample sizes
156-
* are met.
156+
* are met. Provides the data via the callback.
157157
* @param data Pointer to input data.
158158
* @param len Length of input data.
159159
* @param is_final True if this is the last chunk of the box.
@@ -228,45 +228,27 @@ class M4AAudioDemuxer {
228228
channelCfg = chCfg;
229229
}
230230

231-
protected:
232-
Vector<stsz_sample_size_t> sampleSizes; ///< Table of sample sizes.
233-
Vector<uint32_t> chunkOffsets; ///< Table of chunk offsets.
234-
Codec codec = Codec::Unknown; ///< Current codec.
235-
FrameCallback callback = nullptr; ///< Frame callback.
236-
void* ref = nullptr; ///< Reference pointer for callback.
237-
size_t sampleIndex = 0; ///< Current sample index.
238-
SingleBuffer<uint8_t> buffer; ///< Buffer for accumulating sample data.
239-
int aacProfile = 2, sampleRateIdx = 4, channelCfg = 2; ///< AAC config.
240-
uint32_t fixed_sample_size = 0; ///< Fixed sample size (if used).
241-
uint32_t fixed_sample_count = 0; ///< Fixed sample count (if used).
242-
size_t current_size = 0; ///< Current sample size.
243-
size_t box_size = 0; ///< Maximum size of the current sample.
244-
size_t box_pos = 0; ///< Current position in the box.
245-
246231
/**
247-
* @brief Executes the callback for a completed frame.
232+
* @brief Constructs a Frame object for the current codec.
248233
* @param size Size of the frame.
234+
* @param buffer SingleBuffer with data.
235+
* @return Frame object.
249236
*/
250-
void executeCallback(size_t size) {
251-
size_t frameSize = size;
237+
Frame getFrame(size_t size, SingleBuffer<uint8_t>& buffer) {
252238
Frame frame;
253239
frame.codec = codec;
254240
frame.data = buffer.data();
255-
frame.size = frameSize;
241+
frame.size = size;
256242
switch (codec) {
257243
case Codec::AAC: {
258-
uint8_t out[frameSize + 7];
259-
writeAdtsHeader(out, aacProfile, sampleRateIdx, channelCfg,
260-
frameSize);
261-
memcpy(out + 7, buffer.data(), frameSize);
262-
frame.data = out;
263-
frame.size = sizeof(out);
244+
// Prepare ADTS header + AAC frame
245+
tmp.resize(size + 7);
246+
writeAdtsHeader(tmp.data(), aacProfile, sampleRateIdx, channelCfg, size);
247+
memcpy(tmp.data() + 7, buffer.data(), size);
248+
frame.data = tmp.data();
249+
frame.size = size + 7;
264250
frame.mime = "audio/aac";
265-
if (callback)
266-
callback(frame, ref);
267-
else
268-
LOGE("No callback defined for audio frame extraction");
269-
return;
251+
break;
270252
}
271253
case Codec::ALAC:
272254
frame.mime = "audio/alac";
@@ -278,6 +260,31 @@ class M4AAudioDemuxer {
278260
frame.mime = nullptr;
279261
break;
280262
}
263+
return frame;
264+
}
265+
266+
protected:
267+
Vector<stsz_sample_size_t> sampleSizes; ///< Table of sample sizes.
268+
Vector<uint32_t> chunkOffsets; ///< Table of chunk offsets.
269+
Vector<uint8_t> tmp;
270+
Codec codec = Codec::Unknown; ///< Current codec.
271+
FrameCallback callback = nullptr; ///< Frame callback.
272+
void* ref = nullptr; ///< Reference pointer for callback.
273+
size_t sampleIndex = 0; ///< Current sample index.
274+
SingleBuffer<uint8_t> buffer; ///< Buffer for accumulating sample data.
275+
int aacProfile = 2, sampleRateIdx = 4, channelCfg = 2; ///< AAC config.
276+
uint32_t fixed_sample_size = 0; ///< Fixed sample size (if used).
277+
uint32_t fixed_sample_count = 0; ///< Fixed sample count (if used).
278+
size_t current_size = 0; ///< Current sample size.
279+
size_t box_size = 0; ///< Maximum size of the current sample.
280+
size_t box_pos = 0; ///< Current position in the box.
281+
282+
/**
283+
* @brief Executes the callback for a completed frame.
284+
* @param size Size of the frame.
285+
*/
286+
void executeCallback(size_t size) {
287+
Frame frame = getFrame(size, buffer);
281288
if (callback)
282289
callback(frame, ref);
283290
else
@@ -345,6 +352,13 @@ class M4AAudioDemuxer {
345352
// incremental data callback
346353
parser.setIncrementalDataCallback(incrementalBoxDataCallback);
347354

355+
// Register a specific incremental data callback for mdat
356+
parser.setIncrementalDataCallback("mdat", [](MP4Parser::Box& box, const uint8_t* data, size_t len, bool is_final, void* ref) {
357+
auto* self = static_cast<M4AAudioDemuxer*>(ref);
358+
LOGI("*Box: %s, size: %u bytes", box.type, (unsigned)len);
359+
self->sampleExtractor.write(data, len, is_final);
360+
}, false);
361+
348362
// parsing for content of stsd (Sample Description Box)
349363
parser.setCallback("esds", [](MP4Parser::Box& box, void* ref) {
350364
static_cast<M4AAudioDemuxer*>(ref)->onEsds(box);
@@ -355,6 +369,12 @@ class M4AAudioDemuxer {
355369
parser.setCallback("alac", [](MP4Parser::Box& box, void* ref) {
356370
static_cast<M4AAudioDemuxer*>(ref)->onAlac(box);
357371
});
372+
parser.setCallback("mdat", [](MP4Parser::Box& box, void* ref) {
373+
M4AAudioDemuxer& self = *static_cast<M4AAudioDemuxer*>(ref);
374+
// mdat must not be buffered
375+
LOGI("Box: %s, size: %u bytes", box.type, (unsigned)box.size);
376+
self.sampleExtractor.setMaxSize(box.size);
377+
}, false); // 'false' prevents the generic callback from being executed
358378
}
359379

360380
/**
@@ -450,20 +470,15 @@ class M4AAudioDemuxer {
450470
}
451471

452472
/**
453-
* @brief Callback for box data setup.
473+
* @brief Callback for box data setup. If we contain data we add
474+
* it to the buffer. If there is no data we set up the buffer to
475+
* receive incremental data.
454476
* @param box MP4 box.
455477
* @param ref Reference pointer.
456478
*/
457479
static void boxDataSetupCallback(MP4Parser::Box& box, void* ref) {
458480
M4AAudioDemuxer& self = *static_cast<M4AAudioDemuxer*>(ref);
459481

460-
// mdat must not be buffered
461-
if (StrView(box.type) == "mdat") {
462-
LOGI("Box: %s, size: %u bytes", box.type, (unsigned)box.size);
463-
self.sampleExtractor.setMaxSize(box.size);
464-
return;
465-
}
466-
467482
bool is_relevant = isRelevantBox(box.type);
468483
if (is_relevant) {
469484
LOGI("Box: %s, size: %u bytes", box.type, (unsigned)box.size);
@@ -491,13 +506,6 @@ class M4AAudioDemuxer {
491506
bool is_final, void* ref) {
492507
M4AAudioDemuxer& self = *static_cast<M4AAudioDemuxer*>(ref);
493508

494-
// mdat must not be buffered
495-
if (StrView(box.type) == "mdat") {
496-
LOGI("*Box: %s, size: %u bytes", box.type, (unsigned)len);
497-
self.sampleExtractor.write(data, len, is_final);
498-
return;
499-
}
500-
501509
// only process relevant boxes
502510
if (!isRelevantBox(box.type)) return;
503511

src/AudioTools/AudioCodecs/MP4ParserIncremental.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class MP4ParserIncremental : public MP4Parser {
4949
* @param type 4-character box type (e.g. "moov", "mdat").
5050
* @param cb Callback function for this box type.
5151
*/
52-
void setCallback(const char* type, BoxCallback cb) {
53-
MP4Parser::setCallback(type, cb);
52+
void setCallback(const char* type, BoxCallback cb, bool callGeneric = true) {
53+
MP4Parser::setCallback(type, cb, callGeneric);
5454
}
5555

5656
protected:

0 commit comments

Comments
 (0)