Skip to content

Commit dea69cb

Browse files
committed
Attempt to skip corrupt AAC frames.
1 parent b27c41b commit dea69cb

1 file changed

Lines changed: 31 additions & 4 deletions

File tree

  • main/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac

main/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoder.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamWriter;
55
import com.sedmelluq.discord.lavaplayer.tools.io.ByteBufferOutputStream;
66
import com.sedmelluq.lava.common.natives.NativeResourceHolder;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
79

810
import java.io.ByteArrayInputStream;
911
import java.io.IOException;
@@ -16,6 +18,8 @@
1618
* layer. The only AAC type verified to work with this is AAC_LC.
1719
*/
1820
public class AacDecoder extends NativeResourceHolder {
21+
private static final Logger log = LoggerFactory.getLogger(AacDecoder.class);
22+
1923
private static final int[] SAMPLERATE_TABLE = { 96000, 88200, 64000, 48000, 44100,
2024
32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
2125

@@ -31,8 +35,13 @@ public class AacDecoder extends NativeResourceHolder {
3135
private static final int ERROR_NOT_ENOUGH_BITS = 4098;
3236
private static final int ERROR_OUTPUT_BUFFER_TOO_SMALL = 8204;
3337

38+
// per-frame decode errors are in the range 0x4000-0x4FFF
39+
private static final int DECODE_ERROR_START = 0x4000;
40+
private static final int DECODE_ERROR_END = 0x4FFF;
41+
3442
private final AacDecoderLibrary library;
35-
private final long instance;
43+
private long instance;
44+
private Long lastConfig;
3645

3746
/**
3847
* Create a new decoder.
@@ -102,6 +111,7 @@ private synchronized int configureRaw(long buffer) {
102111
buffer = Long.reverseBytes(buffer);
103112
}
104113

114+
lastConfig = buffer;
105115
return library.configure(instance, buffer);
106116
}
107117

@@ -205,11 +215,28 @@ public synchronized boolean decode(ShortBuffer buffer, boolean flush) {
205215
}
206216

207217
int result = library.decode(instance, buffer, buffer.capacity(), flush);
208-
if (result != 0 && result != ERROR_NOT_ENOUGH_BITS) {
209-
throw new IllegalStateException("Error from decoder " + result);
218+
219+
if (result == 0) {
220+
return true;
221+
} else if (result == ERROR_NOT_ENOUGH_BITS) {
222+
return false;
223+
} else if (result >= DECODE_ERROR_START && result <= DECODE_ERROR_END) {
224+
// 0x4xxx errors are per-frame, so we can try to ignore the error and resume from the next frame
225+
log.warn("Skipping corrupt AAC frame, decoder returned error {}.", result);
226+
resetInstance();
227+
return false;
210228
}
211229

212-
return result == 0;
230+
throw new IllegalStateException("Error from decoder " + result);
231+
}
232+
233+
private void resetInstance() {
234+
library.destroy(instance);
235+
instance = library.create(TRANSPORT_NONE);
236+
237+
if (lastConfig != null) {
238+
library.configure(instance, lastConfig);
239+
}
213240
}
214241

215242
/**

0 commit comments

Comments
 (0)