diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java index b02fc1b1b0..3e00bcc902 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java @@ -27,7 +27,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; -/** Utility methods for parsing Dolby TrueHD and (E-)AC3 syncframes. */ +/** + * Utility methods for parsing Dolby TrueHD and (E-)AC-3 syncframes. (E-)AC-3 parsing follows the + * definition in ETSI TS 102 366 V1.2.1. + */ public final class Ac3Util { /** Holds sample format information as presented by a syncframe header. */ @@ -237,7 +240,7 @@ public final class Ac3Util { public static SyncFrameInfo parseAc3SyncframeInfo(ParsableBitArray data) { int initialPosition = data.getPosition(); data.skipBits(40); - boolean isEac3 = data.readBits(5) == 16; + boolean isEac3 = data.readBits(5) == 16; // See bsid in subsection E.1.3.1.6. data.setPosition(initialPosition); String mimeType; @StreamType int streamType = SyncFrameInfo.STREAM_TYPE_UNDEFINED; @@ -265,7 +268,7 @@ public final class Ac3Util { break; } data.skipBits(3); // substreamid - frameSize = (data.readBits(11) + 1) * 2; + frameSize = (data.readBits(11) + 1) * 2; // See frmsiz in subsection E.1.3.1.3. int fscod = data.readBits(2); int audioBlocks; int numblkscod; @@ -451,18 +454,25 @@ public final class Ac3Util { } /** - * Returns the size in bytes of the given AC-3 syncframe. + * Returns the size in bytes of the given (E-)AC-3 syncframe. * * @param data The syncframe to parse. * @return The syncframe size in bytes. {@link C#LENGTH_UNSET} if the input is invalid. */ public static int parseAc3SyncframeSize(byte[] data) { - if (data.length < 5) { + if (data.length < 6) { return C.LENGTH_UNSET; } - int fscod = (data[4] & 0xC0) >> 6; - int frmsizecod = data[4] & 0x3F; - return getAc3SyncframeSize(fscod, frmsizecod); + boolean isEac3 = ((data[5] & 0xFF) >> 3) == 16; // See bsid in subsection E.1.3.1.6. + if (isEac3) { + int frmsiz = (data[2] & 0x07) << 8; // Most significant 3 bits. + frmsiz |= data[3] & 0xFF; // Least significant 8 bits. + return (frmsiz + 1) * 2; // See frmsiz in subsection E.1.3.1.3. + } else { + int fscod = (data[4] & 0xC0) >> 6; + int frmsizecod = data[4] & 0x3F; + return getAc3SyncframeSize(fscod, frmsizecod); + } } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Extractor.java index cd806cfe05..93ce15a7ab 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Extractor.java @@ -85,7 +85,7 @@ public final class Ac3Extractor implements Extractor { int headerPosition = startPosition; int validFramesCount = 0; while (true) { - input.peekFully(scratch.data, 0, 5); + input.peekFully(scratch.data, 0, 6); scratch.setPosition(0); int syncBytes = scratch.readUnsignedShort(); if (syncBytes != AC3_SYNC_WORD) { @@ -103,7 +103,7 @@ public final class Ac3Extractor implements Extractor { if (frameSize == C.LENGTH_UNSET) { return false; } - input.advancePeekPosition(frameSize - 5); + input.advancePeekPosition(frameSize - 6); } } }