Skip to content

Commit 2ecf8b3

Browse files
Tolriqrohitjoins
authored andcommitted
Use streaminfo block for FLAC files.
Some files do not have the sample size in each frame headers, in that case, ffmpeg needs the streaminfo data to properly decode them.
1 parent c683a22 commit 2ecf8b3

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

libraries/decoder_ffmpeg/src/main/java/androidx/media3/decoder/ffmpeg/FfmpegAudioDecoder.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,57 @@ private static byte[] getExtraData(String mimeType, List<byte[]> initializationD
190190
return getAlacExtraData(initializationData);
191191
case MimeTypes.AUDIO_VORBIS:
192192
return getVorbisExtraData(initializationData);
193+
case MimeTypes.AUDIO_FLAC:
194+
return getFlacExtraData(initializationData);
193195
default:
194196
// Other codecs do not require extra data.
195197
return null;
196198
}
197199
}
198200

201+
@Nullable
202+
private static byte[] getFlacExtraData(List<byte[]> initializationData) {
203+
for (int i = 0; i < initializationData.size(); i++) {
204+
byte[] out = extractFlacStreamInfo(initializationData.get(i));
205+
if (out != null) {
206+
return out;
207+
}
208+
}
209+
return null;
210+
}
211+
212+
@Nullable
213+
private static byte[] extractFlacStreamInfo(byte[] data) {
214+
final int STREAMINFO_LEN = 34;
215+
int off = 0;
216+
217+
if (data.length >= 4
218+
&& data[0] == (byte) 'f'
219+
&& data[1] == (byte) 'L'
220+
&& data[2] == (byte) 'a'
221+
&& data[3] == (byte) 'C') {
222+
off = 4;
223+
}
224+
225+
if (data.length - off == STREAMINFO_LEN) {
226+
byte[] out = new byte[STREAMINFO_LEN];
227+
System.arraycopy(data, off, out, 0, STREAMINFO_LEN);
228+
return out;
229+
}
230+
231+
if (data.length >= off + 4) {
232+
int type = data[off] & 0x7F;
233+
int len = ((data[off + 1] & 0xFF) << 16) | ((data[off + 2] & 0xFF) << 8) | (data[off + 3] & 0xFF);
234+
if (type == 0 && len == STREAMINFO_LEN && data.length >= off + 4 + STREAMINFO_LEN) {
235+
byte[] out = new byte[STREAMINFO_LEN];
236+
System.arraycopy(data, off + 4, out, 0, STREAMINFO_LEN);
237+
return out;
238+
}
239+
}
240+
241+
return null;
242+
}
243+
199244
private static byte[] getAlacExtraData(List<byte[]> initializationData) {
200245
// FFmpeg's ALAC decoder expects an ALAC atom, which contains the ALAC "magic cookie", as extra
201246
// data. initializationData[0] contains only the magic cookie, and so we need to package it into

0 commit comments

Comments
 (0)