Skip to content

Commit acfa0ec

Browse files
committed
ContainerM4A: change logic to find ftyp
1 parent deb2ded commit acfa0ec

File tree

2 files changed

+23
-35
lines changed

2 files changed

+23
-35
lines changed

src/AudioTools/AudioCodecs/ContainerM4A.h

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class ContainerM4A : public ContainerDecoder {
6969
bool begin() override {
7070
TRACED();
7171
is_active = true;
72-
state = ParserState::WAITING_FOR_FTYP;
72+
state = ParserState::READING_BOX_HEADER;
7373
audio_track_id = -1;
7474
sample_count = 0;
7575
current_sample = 0;
@@ -99,25 +99,35 @@ class ContainerM4A : public ContainerDecoder {
9999
void end() override {
100100
TRACED();
101101
is_active = false;
102+
ftyp_found = false;
102103
if (p_decoder) p_decoder->end();
103104
}
104105

105106
size_t write(const uint8_t* data, size_t len) override {
106107
if (!is_active || p_print == nullptr) {
107108
return 0;
108109
}
110+
// we expect the file to start with an ftype
111+
int start = 0;
112+
if (!ftyp_found){
113+
start = findFtyp(data, len);
114+
if (start >= 0){
115+
ftyp_found = true;
116+
start -= 4;
117+
} else {
118+
// ignore all data
119+
return len;
120+
}
121+
}
109122

110123
size_t processed = 0;
111124

112125
// Process input data byte by byte
113-
for (size_t i = 0; i < len; i++) {
126+
for (size_t i = start; i < len; i++) {
114127
uint8_t byte = data[i];
115128
processed++;
116129

117130
switch (state) {
118-
case ParserState::WAITING_FOR_FTYP:
119-
processFtyp(byte);
120-
break;
121131

122132
case ParserState::READING_BOX_HEADER:
123133
processBoxHeader(byte);
@@ -143,7 +153,6 @@ class ContainerM4A : public ContainerDecoder {
143153
MultiDecoder* p_decoder = nullptr;
144154

145155
enum class ParserState {
146-
WAITING_FOR_FTYP,
147156
READING_BOX_HEADER,
148157
READING_BOX_DATA,
149158
READING_MDAT
@@ -176,8 +185,9 @@ class ContainerM4A : public ContainerDecoder {
176185
uint64_t chunk_offset; // Using uint64_t to support co64 boxes
177186
};
178187

179-
ParserState state = ParserState::WAITING_FOR_FTYP;
188+
ParserState state = ParserState::READING_BOX_HEADER;
180189
bool is_active = false;
190+
bool ftyp_found = false;
181191

182192
BoxHeader current_box;
183193
Vector<BoxHeader> box_stack; // Track box hierarchy
@@ -237,34 +247,12 @@ class ContainerM4A : public ContainerDecoder {
237247
const char* BOX_HDLR = "hdlr";
238248
const char* BOX_ALAC = "alac";
239249

240-
void processFtyp(uint8_t byte) {
241-
static uint8_t ftyp_signature[] = {'f', 't', 'y', 'p'};
242-
static int signature_pos = 0;
243-
244-
// Skip first 4 bytes (box size)
245-
static int header_pos = 0;
246-
if (header_pos < 4) {
247-
header_pos++;
248-
file_offset++;
249-
return;
250-
}
251-
252-
// Check for ftyp signature
253-
if (byte == ftyp_signature[signature_pos]) {
254-
signature_pos++;
255-
file_offset++;
256-
if (signature_pos == 4) {
257-
// Found ftyp, move to general box parsing
258-
resetBoxHeader();
259-
state = ParserState::READING_BOX_HEADER;
260-
signature_pos = 0;
261-
header_pos = 0;
262-
}
263-
} else {
264-
// Reset if signature doesn't match
265-
signature_pos = 0;
266-
file_offset++;
250+
size_t findFtyp(const uint8_t* data, size_t len) {
251+
for (int j = 0; j < len-4; j++){
252+
if (data[j]=='f' && data[j+1]=='t' && data[j+2]=='y' && data[j+3]=='p')
253+
return true;
267254
}
255+
return false;
268256
}
269257

270258
void resetBoxHeader() {

tests-cmake/codec/m4a/m4a.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ StreamCopy copier(decoder_output, file);
2525

2626
void setup() {
2727
Serial.begin(115200);
28-
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Debug);
28+
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
2929

3030
if (!SD.begin()){
3131
Serial.println("SD Card initialization failed!");

0 commit comments

Comments
 (0)