@@ -41,6 +41,10 @@ class M4AAudioDemuxer {
41
41
sampleIndex = 0 ;
42
42
buffer.clear ();
43
43
sampleSizes.clear ();
44
+ buffer.resize (1024 );
45
+ current_size = 0 ;
46
+ box_pos = 0 ;
47
+ box_size = 0 ;
44
48
}
45
49
46
50
void setCodec (M4AAudioDemuxer::Codec c) { codec = c; }
@@ -49,26 +53,40 @@ class M4AAudioDemuxer {
49
53
50
54
void setReference (void * r) { ref = r; }
51
55
52
- void write (const uint8_t * data, size_t len, bool is_final) {
56
+ // / box size e.g. of mdat
57
+ void setMaxSize (size_t size) { box_size = size; }
58
+
59
+ size_t write (const uint8_t * data, size_t len, bool is_final) {
53
60
// Resize buffer to the current sample size
54
61
size_t currentSize = currentSampleSize ();
55
- resize (currentSize);
56
62
if (currentSize == 0 ) {
57
63
LOGE (" No sample size defined, cannot write data" );
58
- return ;
64
+ return 0 ;
59
65
}
66
+ resize (currentSize);
60
67
61
68
// / fill buffer up to the current sample size
62
69
for (int j = 0 ; j < len; j++) {
63
70
buffer.write (data[j]);
64
71
if (buffer.available () == currentSize) {
72
+ LOGI (" Sample# %zu: size %zu bytes" , sampleIndex, currentSize);
65
73
executeCallback (currentSize);
66
74
buffer.clear ();
75
+ box_pos += currentSize;
67
76
++sampleIndex;
68
77
currentSize = currentSampleSize ();
78
+ if (box_pos >= box_size){
79
+ LOGI (" Reached end of box: %s write" , is_final ? " final" : " not final" );
80
+ return j;
81
+ }
82
+ if (currentSize == 0 ) {
83
+ LOGE (" No sample size defined, cannot write data" );
84
+ return j;
85
+ }
69
86
resize (currentSize);
70
87
}
71
88
}
89
+ return len;
72
90
}
73
91
74
92
Vector<size_t >& getSampleSizes () { return sampleSizes; }
@@ -89,6 +107,9 @@ class M4AAudioDemuxer {
89
107
size_t sampleIndex = 0 ;
90
108
SingleBuffer<uint8_t > buffer;
91
109
int aacProfile = 2 , sampleRateIdx = 4 , channelCfg = 2 ;
110
+ size_t current_size = 0 ; // current sample size
111
+ size_t box_size = 0 ; // maximum size of the current sample
112
+ size_t box_pos = 0 ;
92
113
93
114
void executeCallback (size_t size) {
94
115
size_t frameSize = size;
@@ -106,8 +127,10 @@ class M4AAudioDemuxer {
106
127
frame.data = out;
107
128
frame.size = sizeof (out);
108
129
frame.mime = " audio/aac" ;
109
- if (callback) callback (frame, ref);
110
- else LOGE (" No callback defined for audio frame extraction" );
130
+ if (callback)
131
+ callback (frame, ref);
132
+ else
133
+ LOGE (" No callback defined for audio frame extraction" );
111
134
return ;
112
135
}
113
136
case Codec::ALAC:
@@ -120,8 +143,10 @@ class M4AAudioDemuxer {
120
143
frame.mime = nullptr ;
121
144
break ;
122
145
}
123
- if (callback) callback (frame, ref);
124
- else LOGE (" No callback defined for audio frame extraction" );
146
+ if (callback)
147
+ callback (frame, ref);
148
+ else
149
+ LOGE (" No callback defined for audio frame extraction" );
125
150
}
126
151
127
152
void resize (size_t newSize) {
@@ -159,7 +184,6 @@ class M4AAudioDemuxer {
159
184
160
185
// incremental data callback
161
186
parser.setDataCallback (boxDataCallback);
162
-
163
187
}
164
188
165
189
void setCallback (FrameCallback cb) {
@@ -199,19 +223,29 @@ class M4AAudioDemuxer {
199
223
SingleBuffer<uint8_t > buffer; // buffer to collect incremental data
200
224
SampleExtractor sampleExtractor;
201
225
void * ref = nullptr ;
202
- size_t default_size = 1024 ;
226
+ size_t default_size = 2 * 1024 ;
203
227
204
228
bool isRelevantBox (const char * type) {
205
229
// Check if the box is relevant for audio demuxing
206
230
return (StrView (type) == " stsd" || StrView (type) == " stsz" ||
207
231
StrView (type) == " stco" );
208
232
}
233
+
209
234
// / Just prints the box name and the number of bytes received
210
235
static void boxCallback (MP4Parser::Box& box, void * ref) {
211
236
M4AAudioDemuxer& self = *static_cast <M4AAudioDemuxer*>(ref);
237
+
238
+ // mdat must not be buffered
239
+ if (StrView (box.type ) == " mdat" ) {
240
+ LOGI (" Box: %s, size: %u bytes" , box.type , (unsigned )box.size );
241
+ // self.sampleExtractor.setCodec(self.codec);
242
+ self.sampleExtractor .setMaxSize (box.size );
243
+ return ;
244
+ }
245
+
212
246
bool is_relevant = self.isRelevantBox (box.type );
213
247
if (is_relevant) {
214
- LOGI (" Box: %s, size: %u bytes" , box.type , (unsigned ) box.size );
248
+ LOGI (" Box: %s, size: %u bytes" , box.type , (unsigned )box.size );
215
249
if (box.data_size == 0 ) {
216
250
// setup for increemental processing
217
251
self.resize (box.size );
@@ -229,16 +263,16 @@ class M4AAudioDemuxer {
229
263
230
264
// mdat must not be buffered
231
265
if (StrView (box.type ) == " mdat" ) {
232
- LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned ) len);
233
- // self.sampleExtractor.setCodec(self.codec);
266
+ LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned )len);
267
+ // self.sampleExtractor.setCodec(self.codec);
234
268
self.sampleExtractor .write (data, len, is_final);
235
269
return ;
236
270
}
237
271
238
272
// only process relevant boxes
239
273
if (!self.isRelevantBox (box.type )) return ;
240
274
241
- LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned ) len);
275
+ LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned )len);
242
276
243
277
// others fill buffer incrementally
244
278
if (len > 0 ) {
@@ -260,7 +294,7 @@ class M4AAudioDemuxer {
260
294
}
261
295
}
262
296
263
- void processBox (MP4Parser::Box& box) {
297
+ void processBox (MP4Parser::Box& box) {
264
298
if (StrView (box.type ) == " stsd" ) {
265
299
onStsd (box);
266
300
} else if (StrView (box.type ) == " stsz" ) {
@@ -276,7 +310,7 @@ class M4AAudioDemuxer {
276
310
277
311
void onStsd (const MP4Parser::Box& box) {
278
312
LOGI (" onStsd: %s, size: %zu bytes" , box.type , box.data_size );
279
- const uint8_t * data = box.data ; // skip version/flags ?
313
+ const uint8_t * data = box.data ; // skip version/flags ?
280
314
size_t size = box.data_size ;
281
315
if (size < 8 ) return ;
282
316
uint32_t entryCount = readU32 (data + 4 );
@@ -369,11 +403,11 @@ class M4AAudioDemuxer {
369
403
void onStsz (MP4Parser::Box& box) {
370
404
LOGI (" onStsz: %s, size: %zu bytes" , box.type , box.data_size );
371
405
// Parse stsz box and fill sampleSizes
372
- const uint8_t * data = box.data + 4 ; // skip version/flags
406
+ const uint8_t * data = box.data ; // skip version/flags
373
407
size_t size = box.data_size ;
374
408
if (size < 12 ) return ;
375
- uint32_t sampleSize = readU32 (data);
376
- uint32_t sampleCount = readU32 (data + 4 );
409
+ uint32_t sampleSize = readU32 (data + 4 );
410
+ uint32_t sampleCount = readU32 (data + 8 );
377
411
sampleExtractor.begin ();
378
412
Vector<size_t >& sampleSizes = sampleExtractor.getSampleSizes ();
379
413
if (sampleSize == 0 ) {
@@ -391,7 +425,7 @@ class M4AAudioDemuxer {
391
425
void onStco (MP4Parser::Box& box) {
392
426
LOGI (" onStco: %s, size: %zu bytes" , box.type , box.data_size );
393
427
// Parse stco box and fill chunkOffsets
394
- const uint8_t * data = box.data + 4 ; // skip version/flags
428
+ const uint8_t * data = box.data + 4 ; // skip version/flags
395
429
size_t size = box.data_size ;
396
430
if (size < 4 ) return ;
397
431
uint32_t entryCount = readU32 (data);
0 commit comments