diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java index 22a8b57ef7..7fa45a2a94 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java @@ -79,9 +79,7 @@ import com.google.android.exoplayer2.video.AvcConfig; @Override protected void parsePayload(ParsableByteArray data, long timeUs) throws ParserException { int packetType = data.readUnsignedByte(); - int compositionTimeMs = data.readUnsignedInt24(); - // compositionTimeMs is signed int 24, change unsigned int 24 to signed int 24 - compositionTimeMs = (compositionTimeMs & 0x800000L) >>> 23 == 1 ? (compositionTimeMs | 0xff000000) : compositionTimeMs; + int compositionTimeMs = data.readSignedInt24(); timeUs += compositionTimeMs * 1000L; // Parse avc sequence header in case this was not done before. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java b/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java index 70cb584085..9de86cc3bc 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java @@ -256,6 +256,14 @@ public final class ParsableByteArray { | (data[position++] & 0xFF); } + /** + * Reads the next three bytes as an signed value. + */ + public int readSignedInt24() { + int ui24 = readUnsignedInt24(); + return (ui24 & 0x800000L) >>> 23 == 1 ? (ui24 | 0xff000000) : ui24; + } + /** * Reads the next three bytes as a signed value in little endian order. */ diff --git a/library/core/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java b/library/core/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java index 504a58b4a8..56a4740464 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java @@ -334,6 +334,22 @@ public final class ParsableByteArrayTest { assertThat(byteArray.getPosition()).isEqualTo(3); } + @Test + public void testReadPositiveSignedInt24() { + byte[] data = { 0x01, 0x02, (byte) 0xFF }; + ParsableByteArray byteArray = new ParsableByteArray(data); + assertThat(byteArray.readSignedInt24()).isEqualTo(0x0102FF); + assertThat(byteArray.getPosition()).isEqualTo(3); + } + + @Test + public void testReadNegativeSignedInt24() { + byte[] data = { (byte)0xFF, 0x02, (byte) 0x01 }; + ParsableByteArray byteArray = new ParsableByteArray(data); + assertThat(byteArray.readSignedInt24()).isEqualTo(0xFFFF0201); + assertThat(byteArray.getPosition()).isEqualTo(3); + } + @Test public void testReadLittleEndianUnsignedShort() { ParsableByteArray byteArray = new ParsableByteArray(new byte[] {