Skip to content

Commit 7afd44b

Browse files
committed
FLAC: Proper frame parsing + CRC
1 parent 5ed7bd6 commit 7afd44b

File tree

2 files changed

+87
-9
lines changed

2 files changed

+87
-9
lines changed

Source/MediaInfo/Audio/File_Flac.cpp

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ extern std::string ExtensibleWave_ChannelMask (int32u ChannelMask); //In Multipl
3838
extern std::string ExtensibleWave_ChannelMask2 (int32u ChannelMask); //In Multiple/File_Riff_Elements.cpp
3939
extern std::string ExtensibleWave_ChannelMask_ChannelLayout(int32u ChannelMask); //In Multiple/File_Riff_Elements.cpp
4040

41+
#if MEDIAINFO_TRACE
42+
static void CRC16_Init(int16u* Table, int16u Polynomial)
43+
{
44+
for (size_t Pos = 0; Pos < 256; ++Pos)
45+
{
46+
Table[Pos] = static_cast<int16u>(Pos) << 8;
47+
48+
for (int8u bit = 0; bit < 8; ++bit)
49+
{
50+
if (Table[Pos] & 0x8000)
51+
Table[Pos] = (Table[Pos] << 1) ^ Polynomial;
52+
else
53+
Table[Pos] <<= 1;
54+
}
55+
}
56+
}
57+
#endif // MEDIAINFO_TRACE
58+
4159
//***************************************************************************
4260
// Constructor/Destructor
4361
//***************************************************************************
@@ -119,15 +137,52 @@ void File_Flac::Header_Parse()
119137
BLOCK_TYPE=(int8u)-1;
120138
int16u sync;
121139
bool blocking_strategy;
140+
int8u blocksizebits, sampleratebits, crc;
122141
Get_S2 (15, sync, "0b111111111111100");
123-
Get_SB ( blocking_strategy, "blocking strategy");
124-
Skip_S1( 4, "Blocksize");
125-
Skip_S1( 4, "Sample rate");
126-
Skip_S1( 4, "Channels");
127-
Skip_S1( 3, "Bit depth");
128-
Skip_SB( "Reserved");
142+
Get_SB ( blocking_strategy, "blocking strategy bit"); Param_Info1(blocking_strategy ? "variable block size" : "fixed block size");
143+
Get_S1 ( 4, blocksizebits, "Block Size Bits");
144+
Get_S1 ( 4, sampleratebits, "Sample Rate Bits");
145+
Skip_S1( 4, "Channels Bits");
146+
Skip_S1( 3, "Bit Depth Bits");
147+
Skip_S1( 1, "Reserved");
129148
BS_End();
130-
Skip_B1( "Frame header CRC");
149+
int8u peek;
150+
int8u coded_size{};
151+
Peek_B1(peek);
152+
for (int8u i = 8; i > 0; --i) {
153+
if ((peek >> (i - 1) & 1) == 0)
154+
break;
155+
++coded_size;
156+
}
157+
if (coded_size == 0)
158+
coded_size = 1;
159+
Skip_XX(coded_size, "Coded Number");
160+
if (blocksizebits == 0b0110)
161+
Skip_B1( "Uncommon Block Size");
162+
else if (blocksizebits == 0b0111)
163+
Skip_B2( "Uncommon Block Size");
164+
if (sampleratebits == 0b1100)
165+
Skip_B1( "Uncommon Sample Rate");
166+
else if (sampleratebits == 0b1101 || sampleratebits == 0b1110)
167+
Skip_B2( "Uncommon Sample Rate");
168+
Get_B1(crc, "Frame Header CRC");
169+
#if MEDIAINFO_TRACE
170+
if (Trace_Activated) {
171+
int8u CRC_8 = 0;
172+
const int8u polynomial = 0x07; // x^8 + x^2 + x^1 + x^0
173+
const int8u* CRC_8_Buffer = Buffer + Buffer_Offset;
174+
while (CRC_8_Buffer < Buffer + Buffer_Offset + Element_Offset - 1) {
175+
CRC_8 ^= *CRC_8_Buffer++;
176+
for (int8u i = 0; i < 8; ++i) {
177+
if (CRC_8 & 0x80)
178+
CRC_8 = (CRC_8 << 1) ^ polynomial;
179+
else
180+
CRC_8 <<= 1;
181+
}
182+
}
183+
Param_Info1(CRC_8 == crc ? "OK" : "NOK");
184+
}
185+
#endif // MEDIAINFO_TRACE
131186
Length=IsSub?(Element_Size-Element_Offset):0; // Unknown if raw, else full frame
132187
}
133188
else
@@ -159,13 +214,34 @@ void File_Flac::Data_Parse()
159214
CASE_INFO(VORBIS_COMMENT);
160215
CASE_INFO(CUESHEET);
161216
CASE_INFO(PICTURE);
162-
case (int8u)-1: Element_Name("Frame");
163-
[[fallthrough]];
217+
case (int8u)-1: Element_Name("Frame"); break;
164218
default : Skip_XX(Element_Size, "Data");
165219
}
166220

167221
if (Element_Code==(int8u)-1)
168222
{
223+
if (IsSub && Element_Size > 2) {
224+
Skip_XX(Element_Size - 2, "Subframes");
225+
Element_Begin1("Frame Footer");
226+
int16u crc;
227+
Get_B2(crc, "CRC");
228+
#if MEDIAINFO_TRACE
229+
if (Trace_Activated) {
230+
if (!CRC_16_Table) {
231+
CRC_16_Table.reset(new int16u[256]);
232+
CRC16_Init(CRC_16_Table.get(), 0x8005); // x^16 + x^15 + x^2 + x^0
233+
}
234+
int16u CRC_16 = 0x0000;
235+
const int8u* CRC_16_Buffer = Buffer;
236+
while (CRC_16_Buffer < Buffer + Buffer_Offset + Element_Offset - 2) {
237+
CRC_16 = (CRC_16 << 8) ^ CRC_16_Table[(CRC_16 >> 8) ^ (*CRC_16_Buffer++)];
238+
}
239+
Param_Info1(CRC_16 == crc ? "OK" : "NOK");
240+
}
241+
#endif // MEDIAINFO_TRACE
242+
Element_End0();
243+
}
244+
169245
//No more need data
170246
if (!FromIamf)
171247
File__Tags_Helper::Finish("Flac");

Source/MediaInfo/Audio/File_Flac.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
//---------------------------------------------------------------------------
1919
#include "MediaInfo/Tag/File__Tags.h"
20+
#include <memory>
2021
//---------------------------------------------------------------------------
2122

2223
namespace MediaInfoLib
@@ -64,6 +65,7 @@ private :
6465
//Temp
6566
bool Last_metadata_block;
6667
bool IsAudioFrames;
68+
std::unique_ptr<int16u[]> CRC_16_Table;
6769
};
6870

6971
//***************************************************************************

0 commit comments

Comments
 (0)