Refactor and add release notes

This commit is contained in:
Rohit Singh 2024-04-17 14:57:24 +01:00
parent e1294c0d5c
commit 1ab91a64c2
6 changed files with 40 additions and 32 deletions

View File

@ -17,6 +17,13 @@
count constraints as they only apply for playback.
* Track Selection:
* Extractors:
* MPEG-TS: Roll forward the change ensuring the last frame is rendered by
passing the last access unit of a stream to the sample queue
([#7909](https://github.com/google/ExoPlayer/issues/7909)).
Incorporating fixes to resolve the issues that emerged in I-frame only
HLS streams([#1150](https://github.com/google/ExoPlayer/issues/1150))
and H.262 HLS streams
([#1126](https://github.com/google/ExoPlayer/issues/1126)).
* Audio:
* Video:
* Text:

View File

@ -31,7 +31,7 @@ import androidx.media3.extractor.TrackOutput;
* <li>{@link #seek()} (optional, to reset the state)
* <li>{@link #packetStarted(long, int)} (to signal the start of a new packet)
* <li>{@link #consume(ParsableByteArray)} (zero or more times, to provide packet data)
* <li>{@link #packetFinished()} (to signal the end of the current packet)
* <li>{@link #packetFinished(boolean)} (to signal the end of the current packet)
* <li>Repeat steps 3-5 for subsequent packets
* </ol>
*/

View File

@ -170,7 +170,6 @@ public final class H264Reader implements ElementaryStreamReader {
public void packetFinished(boolean isEndOfInput) {
assertTracksCreated();
if (isEndOfInput) {
sampleReader.getSampleIsKeyframe();
sampleReader.end(totalBytesWritten);
}
}
@ -495,16 +494,24 @@ public final class H264Reader implements ElementaryStreamReader {
sampleIsKeyframe = false;
readingSample = true;
}
return getSampleIsKeyframe();
setSampleIsKeyframe();
return sampleIsKeyframe;
}
public boolean getSampleIsKeyframe() {
public void end(long position) {
setSampleIsKeyframe();
// Output a final sample with the NAL units currently held
nalUnitStartPosition = position;
outputSample(/* offset= */ 0);
readingSample = false;
}
private void setSampleIsKeyframe() {
boolean treatIFrameAsKeyframe =
allowNonIdrKeyframes ? sliceHeader.isISlice() : randomAccessIndicator;
sampleIsKeyframe |=
nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_IDR
|| (treatIFrameAsKeyframe && nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_NON_IDR);
return sampleIsKeyframe;
}
private void outputSample(int offset) {
@ -516,13 +523,6 @@ public final class H264Reader implements ElementaryStreamReader {
output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
}
public void end(long position) {
// Output a final sample with the NAL units currently held
nalUnitStartPosition = position;
outputSample(/* offset= */ 0);
readingSample = false;
}
private static final class SliceHeaderData {
private static final int SLICE_TYPE_I = 2;

View File

@ -175,7 +175,6 @@ public final class H265Reader implements ElementaryStreamReader {
public void packetFinished(boolean isEndOfInput) {
assertTracksCreated();
if (isEndOfInput) {
sampleReader.getSampleIsKeyframe();
sampleReader.end(totalBytesWritten);
}
}
@ -378,9 +377,15 @@ public final class H265Reader implements ElementaryStreamReader {
}
}
public boolean getSampleIsKeyframe() {
public void end(long position) {
sampleIsKeyframe = nalUnitHasKeyframeData;
return sampleIsKeyframe;
// Output a sample with the NAL units since the current nalUnitPosition
outputSample(/* offset= */ (int) (position - nalUnitPosition));
// Output a final sample with the remaining NAL units up to the passed position
samplePosition = nalUnitPosition;
nalUnitPosition = position;
outputSample(/* offset= */ 0);
readingSample = false;
}
private void outputSample(int offset) {
@ -392,16 +397,6 @@ public final class H265Reader implements ElementaryStreamReader {
output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
}
public void end(long position) {
// Output a sample with the NAL units since the current nalUnitPosition
outputSample(/* offset= */ (int) (position - nalUnitPosition));
// Output a final sample with the remaining NAL units up to the passed position
samplePosition = nalUnitPosition;
nalUnitPosition = position;
outputSample(/* offset= */ 0);
readingSample = false;
}
/** Returns whether a NAL unit type is one that occurs before any VCL NAL units in a sample. */
private static boolean isPrefixNalUnit(int nalUnitType) {
return (VPS_NUT <= nalUnitType && nalUnitType <= AUD_NUT) || nalUnitType == PREFIX_SEI_NUT;

View File

@ -160,11 +160,12 @@ public final class PesReader implements TsPayloadReader {
}
}
private void setState(int state) {
this.state = state;
bytesRead = 0;
}
/**
* Determines if the parser can consume a dummy end of input indication.
*
* @param isModeHls {@code True} if operating in HLS (HTTP Live Streaming) mode, {@code false}
* otherwise.
*/
public boolean canConsumeDummyEndOfInput(boolean isModeHls) {
// Pusi only payload to trigger end of sample data is only applicable if
// pes does not have a length field and body is being read, another exclusion
@ -175,6 +176,11 @@ public final class PesReader implements TsPayloadReader {
&& !(isModeHls && reader instanceof H262Reader);
}
private void setState(int state) {
this.state = state;
bytesRead = 0;
}
/**
* 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.

View File

@ -425,8 +425,9 @@ public final class TsExtractor implements Extractor {
public @ReadResult int read(ExtractorInput input, PositionHolder seekPosition)
throws IOException {
long inputLength = input.getLength();
boolean isModeHls = mode == MODE_HLS;
if (tracksEnded) {
boolean canReadDuration = inputLength != C.LENGTH_UNSET && mode != MODE_HLS;
boolean canReadDuration = inputLength != C.LENGTH_UNSET && !isModeHls;
if (canReadDuration && !durationReader.isDurationReadFinished()) {
return durationReader.readDuration(input, seekPosition, pcrPid);
}
@ -452,7 +453,6 @@ public final class TsExtractor implements Extractor {
TsPayloadReader payloadReader = tsPayloadReaders.valueAt(i);
if (payloadReader instanceof PesReader) {
PesReader pesReader = (PesReader) payloadReader;
boolean isModeHls = (mode == MODE_HLS);
if (pesReader.canConsumeDummyEndOfInput(isModeHls)) {
pesReader.consume(new ParsableByteArray(), FLAG_PAYLOAD_UNIT_START_INDICATOR);
}