Send downStreamFormatChanged notification for embedded streams.

This allows listeners to get notified of any change to the embedded tracks.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=181969023
This commit is contained in:
tonihei 2018-01-15 07:55:53 -08:00 committed by Oliver Woodman
parent ebfd5a7fe0
commit cfed8791b0
4 changed files with 154 additions and 51 deletions

View File

@ -46,6 +46,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
public final int primaryTrackType;
private final int[] embeddedTrackTypes;
private final Format[] embeddedTrackFormats;
private final boolean[] embeddedTracksSelected;
private final T chunkSource;
private final SequenceableLoader.Callback<ChunkSampleStream<T>> callback;
@ -65,9 +66,10 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
/* package */ boolean loadingFinished;
/**
* @param primaryTrackType The type of the primary track. One of the {@link C}
* {@code TRACK_TYPE_*} constants.
* @param primaryTrackType The type of the primary track. One of the {@link C} {@code
* TRACK_TYPE_*} constants.
* @param embeddedTrackTypes The types of any embedded tracks, or null.
* @param embeddedTrackFormats The formats of the embedded tracks, or null.
* @param chunkSource A {@link ChunkSource} from which chunks to load are obtained.
* @param callback An {@link Callback} for the stream.
* @param allocator An {@link Allocator} from which allocations can be obtained.
@ -76,11 +78,19 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
* before propagating an error.
* @param eventDispatcher A dispatcher to notify of events.
*/
public ChunkSampleStream(int primaryTrackType, int[] embeddedTrackTypes, T chunkSource,
Callback<ChunkSampleStream<T>> callback, Allocator allocator, long positionUs,
int minLoadableRetryCount, EventDispatcher eventDispatcher) {
public ChunkSampleStream(
int primaryTrackType,
int[] embeddedTrackTypes,
Format[] embeddedTrackFormats,
T chunkSource,
Callback<ChunkSampleStream<T>> callback,
Allocator allocator,
long positionUs,
int minLoadableRetryCount,
EventDispatcher eventDispatcher) {
this.primaryTrackType = primaryTrackType;
this.embeddedTrackTypes = embeddedTrackTypes;
this.embeddedTrackFormats = embeddedTrackFormats;
this.chunkSource = chunkSource;
this.callback = callback;
this.eventDispatcher = eventDispatcher;
@ -555,6 +565,8 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
private final SampleQueue sampleQueue;
private final int index;
private boolean formatNotificationSent;
public EmbeddedSampleStream(ChunkSampleStream<T> parent, SampleQueue sampleQueue, int index) {
this.parent = parent;
this.sampleQueue = sampleQueue;
@ -568,13 +580,20 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
@Override
public int skipData(long positionUs) {
int skipCount;
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
return sampleQueue.advanceToEnd();
skipCount = sampleQueue.advanceToEnd();
} else {
int skipCount = sampleQueue.advanceTo(positionUs, true, true);
return skipCount == SampleQueue.ADVANCE_FAILED ? 0 : skipCount;
skipCount = sampleQueue.advanceTo(positionUs, true, true);
if (skipCount == SampleQueue.ADVANCE_FAILED) {
skipCount = 0;
}
}
if (skipCount > 0) {
maybeNotifyTrackFormatChanged();
}
return skipCount;
}
@Override
public void maybeThrowError() throws IOException {
@ -587,8 +606,13 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) {
return C.RESULT_NOTHING_READ;
}
return sampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished,
lastSeekPositionUs);
int result =
sampleQueue.read(
formatHolder, buffer, formatRequired, loadingFinished, lastSeekPositionUs);
if (result == C.RESULT_BUFFER_READ) {
maybeNotifyTrackFormatChanged();
}
return result;
}
public void release() {
@ -596,6 +620,17 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
embeddedTracksSelected[index] = false;
}
private void maybeNotifyTrackFormatChanged() {
if (!formatNotificationSent) {
eventDispatcher.downstreamFormatChanged(
embeddedTrackTypes[index],
embeddedTrackFormats[index],
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
lastSeekPositionUs);
formatNotificationSent = true;
}
}
}
}

View File

@ -436,26 +436,33 @@ import java.util.Map;
}
AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]);
int primaryTrackGroupIndex = trackGroupCount;
boolean hasEventMessageTrack = primaryGroupHasEventMessageTrackFlags[i];
boolean hasCea608Track = primaryGroupHasCea608TrackFlags[i];
int primaryTrackGroupIndex = trackGroupCount++;
int eventMessageTrackGroupIndex =
primaryGroupHasEventMessageTrackFlags[i] ? trackGroupCount++ : C.INDEX_UNSET;
int cea608TrackGroupIndex =
primaryGroupHasCea608TrackFlags[i] ? trackGroupCount++ : C.INDEX_UNSET;
trackGroups[trackGroupCount] = new TrackGroup(formats);
trackGroupInfos[trackGroupCount++] = TrackGroupInfo.primaryTrack(firstAdaptationSet.type,
adaptationSetIndices, primaryTrackGroupIndex, hasEventMessageTrack, hasCea608Track);
if (hasEventMessageTrack) {
trackGroups[primaryTrackGroupIndex] = new TrackGroup(formats);
trackGroupInfos[primaryTrackGroupIndex] =
TrackGroupInfo.primaryTrack(
firstAdaptationSet.type,
adaptationSetIndices,
primaryTrackGroupIndex,
eventMessageTrackGroupIndex,
cea608TrackGroupIndex);
if (eventMessageTrackGroupIndex != C.INDEX_UNSET) {
Format format = Format.createSampleFormat(firstAdaptationSet.id + ":emsg",
MimeTypes.APPLICATION_EMSG, null, Format.NO_VALUE, null);
trackGroups[trackGroupCount] = new TrackGroup(format);
trackGroupInfos[trackGroupCount++] = TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices,
primaryTrackGroupIndex);
trackGroups[eventMessageTrackGroupIndex] = new TrackGroup(format);
trackGroupInfos[eventMessageTrackGroupIndex] =
TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex);
}
if (hasCea608Track) {
if (cea608TrackGroupIndex != C.INDEX_UNSET) {
Format format = Format.createTextSampleFormat(firstAdaptationSet.id + ":cea608",
MimeTypes.APPLICATION_CEA608, 0, null);
trackGroups[trackGroupCount] = new TrackGroup(format);
trackGroupInfos[trackGroupCount++] = TrackGroupInfo.embeddedCea608Track(
adaptationSetIndices, primaryTrackGroupIndex);
trackGroups[cea608TrackGroupIndex] = new TrackGroup(format);
trackGroupInfos[cea608TrackGroupIndex] =
TrackGroupInfo.embeddedCea608Track(adaptationSetIndices, primaryTrackGroupIndex);
}
}
return trackGroupCount;
@ -476,23 +483,38 @@ import java.util.Map;
TrackSelection selection, long positionUs) {
int embeddedTrackCount = 0;
int[] embeddedTrackTypes = new int[2];
boolean enableEventMessageTrack = trackGroupInfo.hasEmbeddedEventMessageTrack;
Format[] embeddedTrackFormats = new Format[2];
boolean enableEventMessageTrack =
trackGroupInfo.embeddedEventMessageTrackGroupIndex != C.INDEX_UNSET;
if (enableEventMessageTrack) {
embeddedTrackFormats[embeddedTrackCount] =
trackGroups.get(trackGroupInfo.embeddedEventMessageTrackGroupIndex).getFormat(0);
embeddedTrackTypes[embeddedTrackCount++] = C.TRACK_TYPE_METADATA;
}
boolean enableCea608Track = trackGroupInfo.hasEmbeddedCea608Track;
boolean enableCea608Track = trackGroupInfo.embeddedCea608TrackGroupIndex != C.INDEX_UNSET;
if (enableCea608Track) {
embeddedTrackFormats[embeddedTrackCount] =
trackGroups.get(trackGroupInfo.embeddedCea608TrackGroupIndex).getFormat(0);
embeddedTrackTypes[embeddedTrackCount++] = C.TRACK_TYPE_TEXT;
}
if (embeddedTrackCount < embeddedTrackTypes.length) {
embeddedTrackFormats = Arrays.copyOf(embeddedTrackFormats, embeddedTrackCount);
embeddedTrackTypes = Arrays.copyOf(embeddedTrackTypes, embeddedTrackCount);
}
DashChunkSource chunkSource = chunkSourceFactory.createDashChunkSource(
manifestLoaderErrorThrower, manifest, periodIndex, trackGroupInfo.adaptationSetIndices,
selection, trackGroupInfo.trackType, elapsedRealtimeOffset, enableEventMessageTrack,
enableCea608Track);
ChunkSampleStream<DashChunkSource> stream = new ChunkSampleStream<>(trackGroupInfo.trackType,
embeddedTrackTypes, chunkSource, this, allocator, positionUs, minLoadableRetryCount,
ChunkSampleStream<DashChunkSource> stream =
new ChunkSampleStream<>(
trackGroupInfo.trackType,
embeddedTrackTypes,
embeddedTrackFormats,
chunkSource,
this,
allocator,
positionUs,
minLoadableRetryCount,
eventDispatcher);
return stream;
}
@ -578,43 +600,74 @@ import java.util.Map;
public final int eventStreamGroupIndex;
public final int primaryTrackGroupIndex;
public final boolean hasEmbeddedEventMessageTrack;
public final boolean hasEmbeddedCea608Track;
public final int embeddedEventMessageTrackGroupIndex;
public final int embeddedCea608TrackGroupIndex;
public static TrackGroupInfo primaryTrack(int trackType, int[] adaptationSetIndices,
int primaryTrackGroupIndex, boolean hasEmbeddedEventMessageTrack,
boolean hasEmbeddedCea608Track) {
return new TrackGroupInfo(trackType, CATEGORY_PRIMARY, adaptationSetIndices,
primaryTrackGroupIndex, hasEmbeddedEventMessageTrack, hasEmbeddedCea608Track, -1);
public static TrackGroupInfo primaryTrack(
int trackType,
int[] adaptationSetIndices,
int primaryTrackGroupIndex,
int embeddedEventMessageTrackGroupIndex,
int embeddedCea608TrackGroupIndex) {
return new TrackGroupInfo(
trackType,
CATEGORY_PRIMARY,
adaptationSetIndices,
primaryTrackGroupIndex,
embeddedEventMessageTrackGroupIndex,
embeddedCea608TrackGroupIndex,
-1);
}
public static TrackGroupInfo embeddedEmsgTrack(int[] adaptationSetIndices,
int primaryTrackGroupIndex) {
return new TrackGroupInfo(C.TRACK_TYPE_METADATA, CATEGORY_EMBEDDED,
adaptationSetIndices, primaryTrackGroupIndex, false, false, -1);
return new TrackGroupInfo(
C.TRACK_TYPE_METADATA,
CATEGORY_EMBEDDED,
adaptationSetIndices,
primaryTrackGroupIndex,
C.INDEX_UNSET,
C.INDEX_UNSET,
-1);
}
public static TrackGroupInfo embeddedCea608Track(int[] adaptationSetIndices,
int primaryTrackGroupIndex) {
return new TrackGroupInfo(C.TRACK_TYPE_TEXT, CATEGORY_EMBEDDED,
adaptationSetIndices, primaryTrackGroupIndex, false, false, -1);
return new TrackGroupInfo(
C.TRACK_TYPE_TEXT,
CATEGORY_EMBEDDED,
adaptationSetIndices,
primaryTrackGroupIndex,
C.INDEX_UNSET,
C.INDEX_UNSET,
-1);
}
public static TrackGroupInfo mpdEventTrack(int eventStreamIndex) {
return new TrackGroupInfo(C.TRACK_TYPE_METADATA, CATEGORY_MANIFEST_EVENTS,
null, -1, false, false, eventStreamIndex);
return new TrackGroupInfo(
C.TRACK_TYPE_METADATA,
CATEGORY_MANIFEST_EVENTS,
null,
-1,
C.INDEX_UNSET,
C.INDEX_UNSET,
eventStreamIndex);
}
private TrackGroupInfo(int trackType, @TrackGroupCategory int trackGroupCategory,
int[] adaptationSetIndices, int primaryTrackGroupIndex,
boolean hasEmbeddedEventMessageTrack, boolean hasEmbeddedCea608Track,
private TrackGroupInfo(
int trackType,
@TrackGroupCategory int trackGroupCategory,
int[] adaptationSetIndices,
int primaryTrackGroupIndex,
int embeddedEventMessageTrackGroupIndex,
int embeddedCea608TrackGroupIndex,
int eventStreamGroupIndex) {
this.trackType = trackType;
this.adaptationSetIndices = adaptationSetIndices;
this.trackGroupCategory = trackGroupCategory;
this.primaryTrackGroupIndex = primaryTrackGroupIndex;
this.hasEmbeddedEventMessageTrack = hasEmbeddedEventMessageTrack;
this.hasEmbeddedCea608Track = hasEmbeddedCea608Track;
this.embeddedEventMessageTrackGroupIndex = embeddedEventMessageTrackGroupIndex;
this.embeddedCea608TrackGroupIndex = embeddedCea608TrackGroupIndex;
this.eventStreamGroupIndex = eventStreamGroupIndex;
}
}

View File

@ -207,8 +207,16 @@ import java.util.ArrayList;
int streamElementIndex = trackGroups.indexOf(selection.getTrackGroup());
SsChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoaderErrorThrower,
manifest, streamElementIndex, selection, trackEncryptionBoxes);
return new ChunkSampleStream<>(manifest.streamElements[streamElementIndex].type, null,
chunkSource, this, allocator, positionUs, minLoadableRetryCount, eventDispatcher);
return new ChunkSampleStream<>(
manifest.streamElements[streamElementIndex].type,
null,
null,
chunkSource,
this,
allocator,
positionUs,
minLoadableRetryCount,
eventDispatcher);
}
private static TrackGroupArray buildTrackGroups(SsManifest manifest) {

View File

@ -132,8 +132,15 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
protected SampleStream createSampleStream(TrackSelection trackSelection) {
FakeChunkSource chunkSource = chunkSourceFactory.createChunkSource(trackSelection, durationUs);
return new ChunkSampleStream<>(
MimeTypes.getTrackType(trackSelection.getSelectedFormat().sampleMimeType), null,
chunkSource, this, allocator, 0, 3, eventDispatcher);
MimeTypes.getTrackType(trackSelection.getSelectedFormat().sampleMimeType),
null,
null,
chunkSource,
this,
allocator,
0,
3,
eventDispatcher);
}
@Override