From 85826ebc19ff39f9edeae65d7d55a2a3ad948ce1 Mon Sep 17 00:00:00 2001 From: Daniele Sparano Date: Thu, 14 Mar 2024 18:12:50 +0000 Subject: [PATCH] Fix dummy pusi solution for byte range and key frame only NAL stream cases --- .../androidx/media3/extractor/ts/H264Reader.java | 9 +++++++-- .../androidx/media3/extractor/ts/H265Reader.java | 10 ++++++++-- .../androidx/media3/extractor/ts/PesReader.java | 16 ++++++++++++---- .../media3/extractor/ts/TsExtractor.java | 6 +++++- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H264Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H264Reader.java index 4445af067a..2cba271216 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H264Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H264Reader.java @@ -170,6 +170,7 @@ public final class H264Reader implements ElementaryStreamReader { public void packetFinished(boolean isEndOfInput) { assertTracksCreated(); if (isEndOfInput) { + sampleReader.getSampleIsKeyframe(); sampleReader.end(totalBytesWritten); } } @@ -494,6 +495,10 @@ public final class H264Reader implements ElementaryStreamReader { sampleIsKeyframe = false; readingSample = true; } + return getSampleIsKeyframe(); + } + + public boolean getSampleIsKeyframe() { boolean treatIFrameAsKeyframe = allowNonIdrKeyframes ? sliceHeader.isISlice() : randomAccessIndicator; sampleIsKeyframe |= @@ -513,8 +518,8 @@ public final class H264Reader implements ElementaryStreamReader { public void end(long position) { // Output a final sample with the NAL units currently held - nalUnitStartPosition = position; - outputSample(/* offset= */ 0); + nalUnitStartPosition = position + 1; + outputSample(/* offset= */ - 1); readingSample = false; } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java index 7d265852a6..56d4ec7c17 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java @@ -175,6 +175,7 @@ public final class H265Reader implements ElementaryStreamReader { public void packetFinished(boolean isEndOfInput) { assertTracksCreated(); if (isEndOfInput) { + sampleReader.getSampleIsKeyframe(); sampleReader.end(totalBytesWritten); } } @@ -377,6 +378,11 @@ public final class H265Reader implements ElementaryStreamReader { } } + public boolean getSampleIsKeyframe() { + sampleIsKeyframe = nalUnitHasKeyframeData; + return sampleIsKeyframe; + } + private void outputSample(int offset) { if (sampleTimeUs == C.TIME_UNSET) { return; @@ -388,8 +394,8 @@ public final class H265Reader implements ElementaryStreamReader { public void end(long position) { // Output a final sample with the NAL units currently held - nalUnitPosition = position; - outputSample(/* offset= */ 0); + nalUnitPosition = position + 1; + outputSample(/* offset= */ - 1); readingSample = false; } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/PesReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/PesReader.java index 577576817e..acf9af89f8 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/PesReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/PesReader.java @@ -36,10 +36,10 @@ public final class PesReader implements TsPayloadReader { private static final String TAG = "PesReader"; - private static final int STATE_FINDING_HEADER = 0; - private static final int STATE_READING_HEADER = 1; - private static final int STATE_READING_HEADER_EXTENSION = 2; - private static final int STATE_READING_BODY = 3; + public static final int STATE_FINDING_HEADER = 0; + public static final int STATE_READING_HEADER = 1; + public static final int STATE_READING_HEADER_EXTENSION = 2; + public static final int STATE_READING_BODY = 3; private static final int HEADER_SIZE = 9; private static final int MAX_HEADER_EXTENSION_SIZE = 10; @@ -165,6 +165,14 @@ public final class PesReader implements TsPayloadReader { bytesRead = 0; } + public int getState() { + return state; + } + + public boolean hasPacketLength() { + return payloadSize != C.LENGTH_UNSET; + } + /** * Continues a read from the provided {@code source} into a given {@code target}. It's assumed * that the data should be written into {@code target} starting from an offset of zero. diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java index 59781d23c3..ebef2b4b0f 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java @@ -15,6 +15,7 @@ */ package androidx.media3.extractor.ts; +import static androidx.media3.extractor.ts.PesReader.STATE_READING_BODY; import static androidx.media3.extractor.ts.TsPayloadReader.EsInfo.AUDIO_TYPE_UNDEFINED; import static androidx.media3.extractor.ts.TsPayloadReader.FLAG_PAYLOAD_UNIT_START_INDICATOR; import static java.lang.annotation.ElementType.TYPE_USE; @@ -451,7 +452,10 @@ public final class TsExtractor implements Extractor { for (int i = 0; i < tsPayloadReaders.size(); i++) { TsPayloadReader payloadReader = tsPayloadReaders.valueAt(i); if (payloadReader instanceof PesReader) { - payloadReader.consume(new ParsableByteArray(), FLAG_PAYLOAD_UNIT_START_INDICATOR); + PesReader pesReader = (PesReader)payloadReader; + if (pesReader.getState() == STATE_READING_BODY && !pesReader.hasPacketLength()) { + pesReader.consume(new ParsableByteArray(), FLAG_PAYLOAD_UNIT_START_INDICATOR); + } } } return RESULT_END_OF_INPUT;