Skip to content

Commit c0e6f3e

Browse files
authored
Merge pull request #1200 from schreibfaul1/MP3_MAIN_DATA_UNDERFLOW
ESPUIno non-progressive m4a files
2 parents e277a15 + 06f93bc commit c0e6f3e

File tree

6 files changed

+322
-209
lines changed

6 files changed

+322
-209
lines changed

src/Audio.cpp

Lines changed: 270 additions & 194 deletions
Large diffs are not rendered by default.

src/Audio.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,13 @@ class Audio {
234234
bool readMetadata(uint16_t b, uint16_t* readedBytes, bool first = false);
235235
int32_t getChunkSize(uint16_t* readedBytes, bool first = false);
236236
bool readID3V1Tag();
237-
int32_t newInBuffStart(int32_t m_resumeFilePos);
237+
int32_t newInBuffStart(int32_t resumeFilePos);
238238
boolean streamDetection(uint32_t bytesAvail);
239239
uint32_t m4a_correctResumeFilePos();
240240
uint32_t ogg_correctResumeFilePos();
241241
int32_t flac_correctResumeFilePos();
242242
int32_t mp3_correctResumeFilePos();
243+
int32_t wav_correctResumeFilePos();
243244
uint8_t determineOggCodec();
244245
void strlower(char* str);
245246
void trim(char* str);
@@ -322,6 +323,7 @@ class Audio {
322323

323324
SemaphoreHandle_t mutex_playAudioData;
324325
SemaphoreHandle_t mutex_audioTask;
326+
SemaphoreHandle_t mutex_audioTaskIsDecoding;
325327
TaskHandle_t m_audioTaskHandle = nullptr;
326328

327329
#pragma GCC diagnostic push
@@ -362,6 +364,7 @@ class Audio {
362364
uint32_t m_avr_bitrate = 0; // average bitrate, median calculated by VBR
363365
uint32_t m_nominal_bitrate = 0; // given br from header
364366
uint32_t m_audioFilePosition = 0; // current position, counts every readed byte
367+
uint32_t m_audioDataReadPtr = 0; // used in playAudioData
365368
uint32_t m_audioFileSize = 0; // local and web files
366369
int m_readbytes = 0; // bytes read
367370
uint32_t m_metacount = 0; // counts down bytes between metadata

src/audiolib_structs.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct m4aHdr_t { // used in read_M4A_Header
9898
size_t audioDataPos;
9999
size_t cnt;
100100
size_t offset;
101+
uint32_t mdat_startPos;
101102
uint32_t picPos;
102103
uint32_t picLen;
103104
uint32_t ilst_pos;
@@ -116,6 +117,7 @@ struct m4aHdr_t { // used in read_M4A_Header
116117
uint32_t stsz_table_pos;
117118
bool progressive; // Progressive (moov before mdat)
118119
bool version_flags;
120+
bool mdat_seen;
119121
};
120122

121123
struct plCh_t { // used in playChunk

src/mp3_decoder/mp3_decoder.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -552,17 +552,17 @@ int32_t MP3Decoder::findSyncWord(uint8_t* buf, int32_t nBytes) {
552552
// };
553553

554554
typedef struct {
555-
uint8_t mpeg_version; // 0=MPEG2.5, 1=reserved, 2=MPEG2, 3=MPEG1
556-
uint8_t layer; // 0=reserved, 1=Layer III, 2=Layer II, 3=Layer I
557-
bool crc_protected;
558-
uint8_t bitrate_idx;
559-
uint8_t sample_rate_idx;
560-
bool padding;
561-
uint8_t channel_mode;
562-
uint32_t frame_length = 0; // cytes
563-
uint16_t sample_rate_hz; // the actual sampling rate in Hz
564-
uint16_t bitrate_kbps; // the actual bit rate in Kbps
565-
uint16_t samples_per_frame;
555+
uint8_t mpeg_version = 0; // 0=MPEG2.5, 1=reserved, 2=MPEG2, 3=MPEG1
556+
uint8_t layer = 0; // 0=reserved, 1=Layer III, 2=Layer II, 3=Layer I
557+
bool crc_protected = 0;
558+
uint8_t bitrate_idx = 0;
559+
uint8_t sample_rate_idx = 0;
560+
bool padding = 0;
561+
uint8_t channel_mode = 0;
562+
uint32_t frame_length = 0; // cytes
563+
uint16_t sample_rate_hz = 0; // the actual sampling rate in Hz
564+
uint16_t bitrate_kbps = 0; // the actual bit rate in Kbps
565+
uint16_t samples_per_frame = 0;
566566
} Mp3FrameHeader_sync_t;
567567

568568
// SamplingFrequenz-Lookup tables(Beispiel für MPEG1, MPEG2, MPEG2.5)
@@ -644,7 +644,7 @@ int32_t MP3Decoder::findSyncWord(uint8_t* buf, int32_t nBytes) {
644644
uint16_t sample_rate_hz = 0;
645645

646646
// Mapping from MPEG version to sampling rate table
647-
uint8_t sr_table_idx;
647+
uint8_t sr_table_idx = 0;
648648
if (header_info->mpeg_version == 3)
649649
sr_table_idx = 0; // MPEG 1 (0b11)
650650
else if (header_info->mpeg_version == 2)
@@ -1093,11 +1093,31 @@ int32_t MP3Decoder::decode(uint8_t* inbuf, int32_t* bytesLeft, int16_t* outbuf)
10931093
// Skip fake frames
10941094
int frameLen = IsLikelyRealFrame(inbuf, *bytesLeft);
10951095

1096+
if(m_invalid_frame.start == true && m_invalid_frame.timer + 3000 > millis()) m_invalid_frame.start = false;
1097+
10961098
if (frameLen <= 0) {
10971099
int skip = -frameLen;
10981100
if (skip > 0 && skip <= *bytesLeft) {
10991101
*bytesLeft -= skip;
11001102
MP3_LOG_DEBUG("Fakeframe, size %i", frameLen);
1103+
1104+
if (m_invalid_frame.start == false) { // fake frames control
1105+
m_invalid_frame.start = true;
1106+
m_invalid_frame.timer = millis();
1107+
m_invalid_frame.count1 = 0;
1108+
m_invalid_frame.count2 = 0;
1109+
} else {
1110+
m_invalid_frame.count1++;
1111+
if (m_invalid_frame.start && m_invalid_frame.timer + 1000 < millis()) { m_invalid_frame.count2++; }
1112+
if (m_invalid_frame.start && m_invalid_frame.timer + 2000 < millis()) {
1113+
if (m_invalid_frame.count1 > 5 && m_invalid_frame.count2 > 5) {
1114+
// network error
1115+
m_invalid_frame.start = false;
1116+
return MP3_NEED_RESTART;
1117+
}
1118+
}
1119+
}
1120+
11011121
return MP3_NONE; // fakeframe
11021122
}
11031123
// inbuf empty or unusable
@@ -1146,7 +1166,7 @@ int32_t MP3Decoder::decode(uint8_t* inbuf, int32_t* bytesLeft, int16_t* outbuf)
11461166
if (m_MP3DecInfo->nSlots > *bytesLeft) {
11471167
MP3ClearBadFrame(outbuf);
11481168
MP3_LOG_DEBUG("MP3, indata underflow");
1149-
return MP3_NONE;
1169+
return MP3_MAIN_DATA_UNDERFLOW;
11501170
}
11511171

11521172
/* fill main data buffer with enough new data for this frame */

src/mp3_decoder/mp3_decoder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class MP3Decoder : public Decoder {
3535
enum {
3636
MP3_NONE = 0,
3737
MP3_ERR = -1,
38+
MP3_MAIN_DATA_UNDERFLOW = - 2,
39+
MP3_NEED_RESTART = -3,
3840
MP3_STOP = -100,
3941
};
4042

@@ -59,6 +61,8 @@ class MP3Decoder : public Decoder {
5961
ps_ptr<MP3FrameInfo_t> m_MP3FrameInfo;
6062
ps_ptr<char> m_mpeg_version_str;
6163

64+
invalid_frame m_invalid_frame;
65+
6266
// internally used
6367
int32_t IsLikelyRealFrame(const uint8_t* p, int32_t bytesLeft);
6468
void MP3GetLastFrameInfo();

src/mp3_decoder/structs.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,12 @@ typedef struct {
222222
bool padding;
223223
uint8_t channel_mode;
224224
uint32_t frame_length; // In Bytes
225-
} Mp3FrameHeader;
225+
} Mp3FrameHeader;
226+
227+
struct invalid_frame {
228+
uint32_t timer = 0;
229+
bool start = true;
230+
uint32_t count1 = 0;
231+
uint32_t count2 = 0;
232+
233+
};

0 commit comments

Comments
 (0)