@@ -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
0 commit comments