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()) { if (suppressRead()) {
return C.RESULT_NOTHING_READ; return C.RESULT_NOTHING_READ;
} }
maybeNotifyDownstreamFormat(track);
int result = int result =
sampleQueues[track].read( sampleQueues[track].read(
formatHolder, buffer, formatRequired, loadingFinished, lastSeekPositionUs); formatHolder, buffer, formatRequired, loadingFinished, lastSeekPositionUs);
if (result == C.RESULT_BUFFER_READ) { if (result == C.RESULT_NOTHING_READ) {
maybeNotifyTrackFormat(track);
} else if (result == C.RESULT_NOTHING_READ) {
maybeStartDeferredRetry(track); maybeStartDeferredRetry(track);
} }
return result; return result;
@ -439,6 +438,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if (suppressRead()) { if (suppressRead()) {
return 0; return 0;
} }
maybeNotifyDownstreamFormat(track);
SampleQueue sampleQueue = sampleQueues[track]; SampleQueue sampleQueue = sampleQueues[track];
int skipCount; int skipCount;
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) { if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
@ -449,27 +449,24 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
skipCount = 0; skipCount = 0;
} }
} }
if (skipCount > 0) { if (skipCount == 0) {
maybeNotifyTrackFormat(track);
} else {
maybeStartDeferredRetry(track); maybeStartDeferredRetry(track);
} }
return skipCount; return skipCount;
} }
private void maybeNotifyTrackFormat(int track) { private void maybeNotifyDownstreamFormat(int track) {
PreparedState preparedState = getPreparedState(); PreparedState preparedState = getPreparedState();
boolean[] trackFormatNotificationSent = preparedState.trackFormatNotificationSent; boolean[] trackNotifiedDownstreamFormats = preparedState.trackNotifiedDownstreamFormats;
TrackGroupArray tracks = preparedState.tracks; if (!trackNotifiedDownstreamFormats[track]) {
if (!trackFormatNotificationSent[track]) { Format trackFormat = preparedState.tracks.get(track).getFormat(/* index= */ 0);
Format trackFormat = tracks.get(track).getFormat(0);
eventDispatcher.downstreamFormatChanged( eventDispatcher.downstreamFormatChanged(
MimeTypes.getTrackType(trackFormat.sampleMimeType), MimeTypes.getTrackType(trackFormat.sampleMimeType),
trackFormat, trackFormat,
C.SELECTION_REASON_UNKNOWN, C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null, /* trackSelectionData= */ null,
lastSeekPositionUs); 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_PROGRESSIVE_LIVE
: C.DATA_TYPE_MEDIA; : C.DATA_TYPE_MEDIA;
preparedState = preparedState =
new PreparedState( new PreparedState(seekMap, new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
new TrackGroupArray(trackArray),
/* trackEnabledStates= */ new boolean[trackCount],
trackIsAudioVideoFlags,
/* trackFormatNotificationSent= */ new boolean[trackCount],
seekMap);
prepared = true; prepared = true;
listener.onSourceInfoRefreshed(durationUs, seekMap.isSeekable()); listener.onSourceInfoRefreshed(durationUs, seekMap.isSeekable());
Assertions.checkNotNull(callback).onPrepared(this); Assertions.checkNotNull(callback).onPrepared(this);
@ -991,23 +983,20 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/** Stores state that is initialized when preparation completes. */ /** Stores state that is initialized when preparation completes. */
private static final class PreparedState { 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 SeekMap seekMap;
public final TrackGroupArray tracks;
public final boolean[] trackIsAudioVideoFlags;
public final boolean[] trackEnabledStates;
public final boolean[] trackNotifiedDownstreamFormats;
public PreparedState( public PreparedState(
TrackGroupArray tracks, SeekMap seekMap, TrackGroupArray tracks, boolean[] trackIsAudioVideoFlags) {
boolean[] trackEnabledStates,
boolean[] trackIsAudioVideoFlags,
boolean[] trackFormatNotificationSent,
SeekMap seekMap) {
this.tracks = tracks;
this.trackEnabledStates = trackEnabledStates;
this.trackIsAudioVideoFlags = trackIsAudioVideoFlags;
this.trackFormatNotificationSent = trackFormatNotificationSent;
this.seekMap = seekMap; 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 static final int STREAM_STATE_END_OF_STREAM = 2;
private int streamState; private int streamState;
private boolean formatSent; private boolean notifiedDownstreamFormat;
public void reset() { public void reset() {
if (streamState == STREAM_STATE_END_OF_STREAM) { if (streamState == STREAM_STATE_END_OF_STREAM) {
@ -316,6 +316,7 @@ import java.util.Arrays;
@Override @Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
boolean requireFormat) { boolean requireFormat) {
maybeNotifyDownstreamFormat();
if (streamState == STREAM_STATE_END_OF_STREAM) { if (streamState == STREAM_STATE_END_OF_STREAM) {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ; return C.RESULT_BUFFER_READ;
@ -329,7 +330,6 @@ import java.util.Arrays;
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME); buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
buffer.ensureSpaceForWrite(sampleSize); buffer.ensureSpaceForWrite(sampleSize);
buffer.data.put(sampleData, 0, sampleSize); buffer.data.put(sampleData, 0, sampleSize);
sendFormat();
} else { } else {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
} }
@ -341,23 +341,23 @@ import java.util.Arrays;
@Override @Override
public int skipData(long positionUs) { public int skipData(long positionUs) {
maybeNotifyDownstreamFormat();
if (positionUs > 0 && streamState != STREAM_STATE_END_OF_STREAM) { if (positionUs > 0 && streamState != STREAM_STATE_END_OF_STREAM) {
streamState = STREAM_STATE_END_OF_STREAM; streamState = STREAM_STATE_END_OF_STREAM;
sendFormat();
return 1; return 1;
} }
return 0; return 0;
} }
private void sendFormat() { private void maybeNotifyDownstreamFormat() {
if (!formatSent) { if (!notifiedDownstreamFormat) {
eventDispatcher.downstreamFormatChanged( eventDispatcher.downstreamFormatChanged(
MimeTypes.getTrackType(format.sampleMimeType), MimeTypes.getTrackType(format.sampleMimeType),
format, format,
C.SELECTION_REASON_UNKNOWN, C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null, /* trackSelectionData= */ null,
/* mediaTimeUs= */ 0); /* 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 SampleQueue sampleQueue;
private final int index; private final int index;
private boolean formatNotificationSent; private boolean notifiedDownstreamFormat;
public EmbeddedSampleStream(ChunkSampleStream<T> parent, SampleQueue sampleQueue, int index) { public EmbeddedSampleStream(ChunkSampleStream<T> parent, SampleQueue sampleQueue, int index) {
this.parent = parent; this.parent = parent;
@ -758,7 +758,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) { if (isPendingReset()) {
return 0; return 0;
} }
maybeNotifyTrackFormatChanged(); maybeNotifyDownstreamFormat();
int skipCount; int skipCount;
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) { if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
skipCount = sampleQueue.advanceToEnd(); skipCount = sampleQueue.advanceToEnd();
@ -782,7 +782,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) { if (isPendingReset()) {
return C.RESULT_NOTHING_READ; return C.RESULT_NOTHING_READ;
} }
maybeNotifyTrackFormatChanged(); maybeNotifyDownstreamFormat();
return sampleQueue.read( return sampleQueue.read(
formatHolder, buffer, formatRequired, loadingFinished, decodeOnlyUntilPositionUs); formatHolder, buffer, formatRequired, loadingFinished, decodeOnlyUntilPositionUs);
} }
@ -792,15 +792,15 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
embeddedTracksSelected[index] = false; embeddedTracksSelected[index] = false;
} }
private void maybeNotifyTrackFormatChanged() { private void maybeNotifyDownstreamFormat() {
if (!formatNotificationSent) { if (!notifiedDownstreamFormat) {
eventDispatcher.downstreamFormatChanged( eventDispatcher.downstreamFormatChanged(
embeddedTrackTypes[index], embeddedTrackTypes[index],
embeddedTrackFormats[index], embeddedTrackFormats[index],
C.SELECTION_REASON_UNKNOWN, C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null, /* trackSelectionData= */ null,
lastSeekPositionUs); lastSeekPositionUs);
formatNotificationSent = true; notifiedDownstreamFormat = true;
} }
} }
} }

View file

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