From 4f8f87221ead66dab7610c5c2aa2796f33b3b336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=97=E5=8D=8E=E6=A0=8B=28Rabbit=29?= Date: Wed, 18 Oct 2017 23:03:26 +0800 Subject: [PATCH 1/3] Fix FLV AVCVIDEOPACKET -> compositionTimeMs Type from UI 24 to SI 24 --- .../exoplayer2/extractor/flv/VideoTagPayloadReader.java | 3 +++ 1 file changed, 3 insertions(+) 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 8a4d314ee0..6bf91e4824 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 @@ -80,6 +80,9 @@ import com.google.android.exoplayer2.video.AvcConfig; 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 & 0x800000) >> 23 == 1 ? (compositionTimeMs & 0xff000000) : compositionTimeMs; + timeUs += compositionTimeMs * 1000L; // Parse avc sequence header in case this was not done before. if (packetType == AVC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) { From 5895884c53a33c8417f231696b27dd9ef30495f7 Mon Sep 17 00:00:00 2001 From: miaohuadong Date: Thu, 19 Oct 2017 14:10:18 +0800 Subject: [PATCH 2/3] Fix bug --- .../android/exoplayer2/extractor/flv/VideoTagPayloadReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6bf91e4824..22a8b57ef7 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 @@ -81,7 +81,7 @@ import com.google.android.exoplayer2.video.AvcConfig; int packetType = data.readUnsignedByte(); int compositionTimeMs = data.readUnsignedInt24(); // compositionTimeMs is signed int 24, change unsigned int 24 to signed int 24 - compositionTimeMs = (compositionTimeMs & 0x800000) >> 23 == 1 ? (compositionTimeMs & 0xff000000) : compositionTimeMs; + compositionTimeMs = (compositionTimeMs & 0x800000L) >>> 23 == 1 ? (compositionTimeMs | 0xff000000) : compositionTimeMs; timeUs += compositionTimeMs * 1000L; // Parse avc sequence header in case this was not done before. From 69e50a43a8104723fdf2f37d477f27f1f1ee40a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=97=E5=8D=8E=E6=A0=8B=28Rabbit=29?= Date: Thu, 19 Oct 2017 23:18:12 +0800 Subject: [PATCH 3/3] add readSignedInt24 in ParsableByteArray --- .../extractor/flv/VideoTagPayloadReader.java | 4 +--- .../exoplayer2/util/ParsableByteArray.java | 8 ++++++++ .../exoplayer2/util/ParsableByteArrayTest.java | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) 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[] {