Skip to content

Commit 3752ec5

Browse files
committed
SampleExtractor: track position
1 parent c3e5f08 commit 3752ec5

File tree

2 files changed

+53
-20
lines changed

2 files changed

+53
-20
lines changed

src/AudioTools/AudioCodecs/M4AAudioDemuxer.h

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class M4AAudioDemuxer {
4141
sampleIndex = 0;
4242
buffer.clear();
4343
sampleSizes.clear();
44+
buffer.resize(1024);
45+
current_size = 0;
46+
box_pos = 0;
47+
box_size = 0;
4448
}
4549

4650
void setCodec(M4AAudioDemuxer::Codec c) { codec = c; }
@@ -49,26 +53,40 @@ class M4AAudioDemuxer {
4953

5054
void setReference(void* r) { ref = r; }
5155

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) {
5360
// Resize buffer to the current sample size
5461
size_t currentSize = currentSampleSize();
55-
resize(currentSize);
5662
if (currentSize == 0) {
5763
LOGE("No sample size defined, cannot write data");
58-
return;
64+
return 0;
5965
}
66+
resize(currentSize);
6067

6168
/// fill buffer up to the current sample size
6269
for (int j = 0; j < len; j++) {
6370
buffer.write(data[j]);
6471
if (buffer.available() == currentSize) {
72+
LOGI("Sample# %zu: size %zu bytes", sampleIndex, currentSize);
6573
executeCallback(currentSize);
6674
buffer.clear();
75+
box_pos += currentSize;
6776
++sampleIndex;
6877
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+
}
6986
resize(currentSize);
7087
}
7188
}
89+
return len;
7290
}
7391

7492
Vector<size_t>& getSampleSizes() { return sampleSizes; }
@@ -89,6 +107,9 @@ class M4AAudioDemuxer {
89107
size_t sampleIndex = 0;
90108
SingleBuffer<uint8_t> buffer;
91109
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;
92113

93114
void executeCallback(size_t size) {
94115
size_t frameSize = size;
@@ -106,8 +127,10 @@ class M4AAudioDemuxer {
106127
frame.data = out;
107128
frame.size = sizeof(out);
108129
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");
111134
return;
112135
}
113136
case Codec::ALAC:
@@ -120,8 +143,10 @@ class M4AAudioDemuxer {
120143
frame.mime = nullptr;
121144
break;
122145
}
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");
125150
}
126151

127152
void resize(size_t newSize) {
@@ -159,7 +184,6 @@ class M4AAudioDemuxer {
159184

160185
// incremental data callback
161186
parser.setDataCallback(boxDataCallback);
162-
163187
}
164188

165189
void setCallback(FrameCallback cb) {
@@ -199,19 +223,29 @@ class M4AAudioDemuxer {
199223
SingleBuffer<uint8_t> buffer; // buffer to collect incremental data
200224
SampleExtractor sampleExtractor;
201225
void* ref = nullptr;
202-
size_t default_size = 1024;
226+
size_t default_size = 2 * 1024;
203227

204228
bool isRelevantBox(const char* type) {
205229
// Check if the box is relevant for audio demuxing
206230
return (StrView(type) == "stsd" || StrView(type) == "stsz" ||
207231
StrView(type) == "stco");
208232
}
233+
209234
/// Just prints the box name and the number of bytes received
210235
static void boxCallback(MP4Parser::Box& box, void* ref) {
211236
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+
212246
bool is_relevant = self.isRelevantBox(box.type);
213247
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);
215249
if (box.data_size == 0) {
216250
// setup for increemental processing
217251
self.resize(box.size);
@@ -229,16 +263,16 @@ class M4AAudioDemuxer {
229263

230264
// mdat must not be buffered
231265
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);
234268
self.sampleExtractor.write(data, len, is_final);
235269
return;
236270
}
237271

238272
// only process relevant boxes
239273
if (!self.isRelevantBox(box.type)) return;
240274

241-
LOGI("*Box: %s, size: %u bytes", box.type, (unsigned) len);
275+
LOGI("*Box: %s, size: %u bytes", box.type, (unsigned)len);
242276

243277
// others fill buffer incrementally
244278
if (len > 0) {
@@ -260,7 +294,7 @@ class M4AAudioDemuxer {
260294
}
261295
}
262296

263-
void processBox(MP4Parser::Box& box) {
297+
void processBox(MP4Parser::Box& box) {
264298
if (StrView(box.type) == "stsd") {
265299
onStsd(box);
266300
} else if (StrView(box.type) == "stsz") {
@@ -276,7 +310,7 @@ class M4AAudioDemuxer {
276310

277311
void onStsd(const MP4Parser::Box& box) {
278312
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 ?
280314
size_t size = box.data_size;
281315
if (size < 8) return;
282316
uint32_t entryCount = readU32(data + 4);
@@ -369,11 +403,11 @@ class M4AAudioDemuxer {
369403
void onStsz(MP4Parser::Box& box) {
370404
LOGI("onStsz: %s, size: %zu bytes", box.type, box.data_size);
371405
// 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
373407
size_t size = box.data_size;
374408
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);
377411
sampleExtractor.begin();
378412
Vector<size_t>& sampleSizes = sampleExtractor.getSampleSizes();
379413
if (sampleSize == 0) {
@@ -391,7 +425,7 @@ class M4AAudioDemuxer {
391425
void onStco(MP4Parser::Box& box) {
392426
LOGI("onStco: %s, size: %zu bytes", box.type, box.data_size);
393427
// 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
395429
size_t size = box.data_size;
396430
if (size < 4) return;
397431
uint32_t entryCount = readU32(data);

src/AudioTools/AudioCodecs/MP4Parser.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ class MP4Parser {
267267
box.size = 0;
268268
box.data_size = j;
269269
box.level = static_cast<int>(levelStack.size()) + 1;
270-
;
271270
box.data = buffer.data() + parseOffset;
272271
processCallback();
273272
}

0 commit comments

Comments
 (0)