mirror of
https://github.com/androidx/media.git
synced 2025-05-13 10:39:51 +08:00
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:
parent
ebfd5a7fe0
commit
cfed8791b0
@ -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,12 +580,19 @@ 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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,24 +483,39 @@ 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,
|
||||
eventDispatcher);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user