Clean up easy cases of downstream format notification

- This makes it so that onDownstreamFormatChanged will occur before the corresponding
  renderer event. This was not previously the case, since the renderer would typically
  read the format (and report its event), then a sample (causing the
  onDownstreamFormatChanged event).
- The remaining ones to update are ChunkSampleStream (DASH + HLS), which will be done
  in a way that fixes #4533, and HLS.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=212434874
This commit is contained in:
olly 2018-09-11 05:15:52 -07:00 committed by Oliver Woodman
parent 6c3c71b554
commit 46af49e282
4 changed files with 42 additions and 51 deletions

View file

@ -424,12 +424,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if (suppressRead()) {
return C.RESULT_NOTHING_READ;
}
maybeNotifyDownstreamFormat(track);
int result =
sampleQueues[track].read(
formatHolder, buffer, formatRequired, loadingFinished, lastSeekPositionUs);
if (result == C.RESULT_BUFFER_READ) {
maybeNotifyTrackFormat(track);
} else if (result == C.RESULT_NOTHING_READ) {
if (result == C.RESULT_NOTHING_READ) {
maybeStartDeferredRetry(track);
}
return result;
@ -439,6 +438,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if (suppressRead()) {
return 0;
}
maybeNotifyDownstreamFormat(track);
SampleQueue sampleQueue = sampleQueues[track];
int skipCount;
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
@ -449,27 +449,24 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
skipCount = 0;
}
}
if (skipCount > 0) {
maybeNotifyTrackFormat(track);
} else {
if (skipCount == 0) {
maybeStartDeferredRetry(track);
}
return skipCount;
}
private void maybeNotifyTrackFormat(int track) {
private void maybeNotifyDownstreamFormat(int track) {
PreparedState preparedState = getPreparedState();
boolean[] trackFormatNotificationSent = preparedState.trackFormatNotificationSent;
TrackGroupArray tracks = preparedState.tracks;
if (!trackFormatNotificationSent[track]) {
Format trackFormat = tracks.get(track).getFormat(0);
boolean[] trackNotifiedDownstreamFormats = preparedState.trackNotifiedDownstreamFormats;
if (!trackNotifiedDownstreamFormats[track]) {
Format trackFormat = preparedState.tracks.get(track).getFormat(/* index= */ 0);
eventDispatcher.downstreamFormatChanged(
MimeTypes.getTrackType(trackFormat.sampleMimeType),
trackFormat,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
lastSeekPositionUs);
trackFormatNotificationSent[track] = true;
trackNotifiedDownstreamFormats[track] = true;
}
}
@ -664,12 +661,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
? C.DATA_TYPE_MEDIA_PROGRESSIVE_LIVE
: C.DATA_TYPE_MEDIA;
preparedState =
new PreparedState(
new TrackGroupArray(trackArray),
/* trackEnabledStates= */ new boolean[trackCount],
trackIsAudioVideoFlags,
/* trackFormatNotificationSent= */ new boolean[trackCount],
seekMap);
new PreparedState(seekMap, new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
prepared = true;
listener.onSourceInfoRefreshed(durationUs, seekMap.isSeekable());
Assertions.checkNotNull(callback).onPrepared(this);
@ -991,23 +983,20 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/** Stores state that is initialized when preparation completes. */
private static final class PreparedState {
public final TrackGroupArray tracks;
public final boolean[] trackEnabledStates;
public final boolean[] trackIsAudioVideoFlags;
public final boolean[] trackFormatNotificationSent;
public final SeekMap seekMap;
public final TrackGroupArray tracks;
public final boolean[] trackIsAudioVideoFlags;
public final boolean[] trackEnabledStates;
public final boolean[] trackNotifiedDownstreamFormats;
public PreparedState(
TrackGroupArray tracks,
boolean[] trackEnabledStates,
boolean[] trackIsAudioVideoFlags,
boolean[] trackFormatNotificationSent,
SeekMap seekMap) {
this.tracks = tracks;
this.trackEnabledStates = trackEnabledStates;
this.trackIsAudioVideoFlags = trackIsAudioVideoFlags;
this.trackFormatNotificationSent = trackFormatNotificationSent;
SeekMap seekMap, TrackGroupArray tracks, boolean[] trackIsAudioVideoFlags) {
this.seekMap = seekMap;
this.tracks = tracks;
this.trackIsAudioVideoFlags = trackIsAudioVideoFlags;
this.trackEnabledStates = new boolean[tracks.length];
this.trackNotifiedDownstreamFormats = new boolean[tracks.length];
}
}
}

View file

@ -293,7 +293,7 @@ import java.util.Arrays;
private static final int STREAM_STATE_END_OF_STREAM = 2;
private int streamState;
private boolean formatSent;
private boolean notifiedDownstreamFormat;
public void reset() {
if (streamState == STREAM_STATE_END_OF_STREAM) {
@ -316,6 +316,7 @@ import java.util.Arrays;
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
boolean requireFormat) {
maybeNotifyDownstreamFormat();
if (streamState == STREAM_STATE_END_OF_STREAM) {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ;
@ -329,7 +330,6 @@ import java.util.Arrays;
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
buffer.ensureSpaceForWrite(sampleSize);
buffer.data.put(sampleData, 0, sampleSize);
sendFormat();
} else {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
}
@ -341,23 +341,23 @@ import java.util.Arrays;
@Override
public int skipData(long positionUs) {
maybeNotifyDownstreamFormat();
if (positionUs > 0 && streamState != STREAM_STATE_END_OF_STREAM) {
streamState = STREAM_STATE_END_OF_STREAM;
sendFormat();
return 1;
}
return 0;
}
private void sendFormat() {
if (!formatSent) {
private void maybeNotifyDownstreamFormat() {
if (!notifiedDownstreamFormat) {
eventDispatcher.downstreamFormatChanged(
MimeTypes.getTrackType(format.sampleMimeType),
format,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaTimeUs= */ 0);
formatSent = true;
notifiedDownstreamFormat = true;
}
}
}

View file

@ -740,7 +740,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
private final SampleQueue sampleQueue;
private final int index;
private boolean formatNotificationSent;
private boolean notifiedDownstreamFormat;
public EmbeddedSampleStream(ChunkSampleStream<T> parent, SampleQueue sampleQueue, int index) {
this.parent = parent;
@ -758,7 +758,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) {
return 0;
}
maybeNotifyTrackFormatChanged();
maybeNotifyDownstreamFormat();
int skipCount;
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
skipCount = sampleQueue.advanceToEnd();
@ -782,7 +782,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) {
return C.RESULT_NOTHING_READ;
}
maybeNotifyTrackFormatChanged();
maybeNotifyDownstreamFormat();
return sampleQueue.read(
formatHolder, buffer, formatRequired, loadingFinished, decodeOnlyUntilPositionUs);
}
@ -792,15 +792,15 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
embeddedTracksSelected[index] = false;
}
private void maybeNotifyTrackFormatChanged() {
if (!formatNotificationSent) {
private void maybeNotifyDownstreamFormat() {
if (!notifiedDownstreamFormat) {
eventDispatcher.downstreamFormatChanged(
embeddedTrackTypes[index],
embeddedTrackFormats[index],
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
lastSeekPositionUs);
formatNotificationSent = true;
notifiedDownstreamFormat = true;
}
}
}

View file

@ -33,6 +33,7 @@ public final class FakeSampleStream implements SampleStream {
private final Format format;
private final @Nullable EventDispatcher eventDispatcher;
private boolean notifiedDownstreamFormat;
private boolean readFormat;
private boolean readSample;
@ -59,6 +60,15 @@ public final class FakeSampleStream implements SampleStream {
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
boolean formatRequired) {
if (eventDispatcher != null && !notifiedDownstreamFormat) {
eventDispatcher.downstreamFormatChanged(
C.TRACK_TYPE_UNKNOWN,
format,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaTimeUs= */ 0);
notifiedDownstreamFormat = true;
}
if (formatRequired || !readFormat) {
formatHolder.format = format;
readFormat = true;
@ -69,14 +79,6 @@ public final class FakeSampleStream implements SampleStream {
buffer.data.put((byte) 0);
buffer.flip();
readSample = true;
if (eventDispatcher != null) {
eventDispatcher.downstreamFormatChanged(
C.TRACK_TYPE_UNKNOWN,
format,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaTimeUs= */ 0);
}
return C.RESULT_BUFFER_READ;
} else {
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);