Search in sources :

Example 1 with EventStream

use of com.google.android.exoplayer2.source.dash.manifest.EventStream in project ExoPlayer by google.

the class DashMediaPeriod method buildTrackGroups.

private static Pair<TrackGroupArray, TrackGroupInfo[]> buildTrackGroups(DrmSessionManager drmSessionManager, List<AdaptationSet> adaptationSets, List<EventStream> eventStreams) {
    int[][] groupedAdaptationSetIndices = getGroupedAdaptationSetIndices(adaptationSets);
    int primaryGroupCount = groupedAdaptationSetIndices.length;
    boolean[] primaryGroupHasEventMessageTrackFlags = new boolean[primaryGroupCount];
    Format[][] primaryGroupClosedCaptionTrackFormats = new Format[primaryGroupCount][];
    int totalEmbeddedTrackGroupCount = identifyEmbeddedTracks(primaryGroupCount, adaptationSets, groupedAdaptationSetIndices, primaryGroupHasEventMessageTrackFlags, primaryGroupClosedCaptionTrackFormats);
    int totalGroupCount = primaryGroupCount + totalEmbeddedTrackGroupCount + eventStreams.size();
    TrackGroup[] trackGroups = new TrackGroup[totalGroupCount];
    TrackGroupInfo[] trackGroupInfos = new TrackGroupInfo[totalGroupCount];
    int trackGroupCount = buildPrimaryAndEmbeddedTrackGroupInfos(drmSessionManager, adaptationSets, groupedAdaptationSetIndices, primaryGroupCount, primaryGroupHasEventMessageTrackFlags, primaryGroupClosedCaptionTrackFormats, trackGroups, trackGroupInfos);
    buildManifestEventTrackGroupInfos(eventStreams, trackGroups, trackGroupInfos, trackGroupCount);
    return Pair.create(new TrackGroupArray(trackGroups), trackGroupInfos);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray)

Example 2 with EventStream

use of com.google.android.exoplayer2.source.dash.manifest.EventStream in project ExoPlayer by google.

the class DashMediaPeriod method selectNewStreams.

private void selectNewStreams(ExoTrackSelection[] selections, SampleStream[] streams, boolean[] streamResetFlags, long positionUs, int[] streamIndexToTrackGroupIndex) {
    // Create newly selected primary and event streams.
    for (int i = 0; i < selections.length; i++) {
        ExoTrackSelection selection = selections[i];
        if (selection == null) {
            continue;
        }
        if (streams[i] == null) {
            // Create new stream for selection.
            streamResetFlags[i] = true;
            int trackGroupIndex = streamIndexToTrackGroupIndex[i];
            TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
            if (trackGroupInfo.trackGroupCategory == TrackGroupInfo.CATEGORY_PRIMARY) {
                streams[i] = buildSampleStream(trackGroupInfo, selection, positionUs);
            } else if (trackGroupInfo.trackGroupCategory == TrackGroupInfo.CATEGORY_MANIFEST_EVENTS) {
                EventStream eventStream = eventStreams.get(trackGroupInfo.eventStreamGroupIndex);
                Format format = selection.getTrackGroup().getFormat(0);
                streams[i] = new EventSampleStream(eventStream, format, manifest.dynamic);
            }
        } else if (streams[i] instanceof ChunkSampleStream) {
            // Update selection in existing stream.
            @SuppressWarnings("unchecked") ChunkSampleStream<DashChunkSource> stream = (ChunkSampleStream<DashChunkSource>) streams[i];
            stream.getChunkSource().updateTrackSelection(selection);
        }
    }
    // pass if the index of the primary stream is greater than the index of the embedded stream.
    for (int i = 0; i < selections.length; i++) {
        if (streams[i] == null && selections[i] != null) {
            int trackGroupIndex = streamIndexToTrackGroupIndex[i];
            TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
            if (trackGroupInfo.trackGroupCategory == TrackGroupInfo.CATEGORY_EMBEDDED) {
                int primaryStreamIndex = getPrimaryStreamIndex(i, streamIndexToTrackGroupIndex);
                if (primaryStreamIndex == C.INDEX_UNSET) {
                    // If an embedded track is selected without the corresponding primary track, create an
                    // empty sample stream instead.
                    streams[i] = new EmptySampleStream();
                } else {
                    streams[i] = ((ChunkSampleStream) streams[primaryStreamIndex]).selectEmbeddedTrack(positionUs, trackGroupInfo.trackType);
                }
            }
        }
    }
}
Also used : Format(com.google.android.exoplayer2.Format) EmptySampleStream(com.google.android.exoplayer2.source.EmptySampleStream) ChunkSampleStream(com.google.android.exoplayer2.source.chunk.ChunkSampleStream) ExoTrackSelection(com.google.android.exoplayer2.trackselection.ExoTrackSelection) EventStream(com.google.android.exoplayer2.source.dash.manifest.EventStream)

Example 3 with EventStream

use of com.google.android.exoplayer2.source.dash.manifest.EventStream in project ExoPlayer by google.

the class DashMediaPeriod method updateManifest.

/**
 * Updates the {@link DashManifest} and the index of this period in the manifest.
 *
 * @param manifest The updated manifest.
 * @param periodIndex the new index of this period in the updated manifest.
 */
public void updateManifest(DashManifest manifest, int periodIndex) {
    this.manifest = manifest;
    this.periodIndex = periodIndex;
    playerEmsgHandler.updateManifest(manifest);
    if (sampleStreams != null) {
        for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
            sampleStream.getChunkSource().updateManifest(manifest, periodIndex);
        }
        callback.onContinueLoadingRequested(this);
    }
    eventStreams = manifest.getPeriod(periodIndex).eventStreams;
    for (EventSampleStream eventSampleStream : eventSampleStreams) {
        for (EventStream eventStream : eventStreams) {
            if (eventStream.id().equals(eventSampleStream.eventStreamId())) {
                int lastPeriodIndex = manifest.getPeriodCount() - 1;
                eventSampleStream.updateEventStream(eventStream, /* eventStreamAppendable= */
                manifest.dynamic && periodIndex == lastPeriodIndex);
                break;
            }
        }
    }
}
Also used : EventStream(com.google.android.exoplayer2.source.dash.manifest.EventStream)

Example 4 with EventStream

use of com.google.android.exoplayer2.source.dash.manifest.EventStream in project ExoPlayer by google.

the class DashManifestParser method parsePeriod.

protected Pair<Period, Long> parsePeriod(XmlPullParser xpp, List<BaseUrl> parentBaseUrls, long defaultStartMs, long baseUrlAvailabilityTimeOffsetUs, long availabilityStartTimeMs, long timeShiftBufferDepthMs, boolean dvbProfileDeclared) throws XmlPullParserException, IOException {
    @Nullable String id = xpp.getAttributeValue(null, "id");
    long startMs = parseDuration(xpp, "start", defaultStartMs);
    long periodStartUnixTimeMs = availabilityStartTimeMs != C.TIME_UNSET ? availabilityStartTimeMs + startMs : C.TIME_UNSET;
    long durationMs = parseDuration(xpp, "duration", C.TIME_UNSET);
    @Nullable SegmentBase segmentBase = null;
    @Nullable Descriptor assetIdentifier = null;
    List<AdaptationSet> adaptationSets = new ArrayList<>();
    List<EventStream> eventStreams = new ArrayList<>();
    ArrayList<BaseUrl> baseUrls = new ArrayList<>();
    boolean seenFirstBaseUrl = false;
    long segmentBaseAvailabilityTimeOffsetUs = C.TIME_UNSET;
    do {
        xpp.next();
        if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) {
            if (!seenFirstBaseUrl) {
                baseUrlAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, baseUrlAvailabilityTimeOffsetUs);
                seenFirstBaseUrl = true;
            }
            baseUrls.addAll(parseBaseUrl(xpp, parentBaseUrls, dvbProfileDeclared));
        } else if (XmlPullParserUtil.isStartTag(xpp, "AdaptationSet")) {
            adaptationSets.add(parseAdaptationSet(xpp, !baseUrls.isEmpty() ? baseUrls : parentBaseUrls, segmentBase, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, periodStartUnixTimeMs, timeShiftBufferDepthMs, dvbProfileDeclared));
        } else if (XmlPullParserUtil.isStartTag(xpp, "EventStream")) {
            eventStreams.add(parseEventStream(xpp));
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
            segmentBase = parseSegmentBase(xpp, /* parent= */
            null);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
            segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, /* parentAvailabilityTimeOffsetUs= */
            C.TIME_UNSET);
            segmentBase = parseSegmentList(xpp, /* parent= */
            null, periodStartUnixTimeMs, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
            segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, /* parentAvailabilityTimeOffsetUs= */
            C.TIME_UNSET);
            segmentBase = parseSegmentTemplate(xpp, /* parent= */
            null, ImmutableList.of(), periodStartUnixTimeMs, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
        } else if (XmlPullParserUtil.isStartTag(xpp, "AssetIdentifier")) {
            assetIdentifier = parseDescriptor(xpp, "AssetIdentifier");
        } else {
            maybeSkipTag(xpp);
        }
    } while (!XmlPullParserUtil.isEndTag(xpp, "Period"));
    return Pair.create(buildPeriod(id, startMs, adaptationSets, eventStreams, assetIdentifier), durationMs);
}
Also used : ArrayList(java.util.ArrayList) SingleSegmentBase(com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase) Nullable(androidx.annotation.Nullable)

Example 5 with EventStream

use of com.google.android.exoplayer2.source.dash.manifest.EventStream in project ExoPlayer by google.

the class EventSampleStreamTest method seekToUsThenReadDataReturnDataFromSeekPosition.

/**
 * Tests that {@link EventSampleStream#seekToUs(long)} (long)} will seek to the given position,
 * and the next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call
 * will return sample data from that position.
 */
@Test
public void seekToUsThenReadDataReturnDataFromSeekPosition() {
    long presentationTimeUs1 = 1000000;
    long presentationTimeUs2 = 2000000;
    EventMessage eventMessage1 = newEventMessageWithId(1);
    EventMessage eventMessage2 = newEventMessageWithId(2);
    EventStream eventStream = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] { presentationTimeUs1, presentationTimeUs2 }, new EventMessage[] { eventMessage1, eventMessage2 });
    EventSampleStream sampleStream = new EventSampleStream(eventStream, FORMAT, false);
    // first read - read format
    readData(sampleStream);
    sampleStream.seekToUs(presentationTimeUs2);
    int result = readData(sampleStream);
    assertThat(result).isEqualTo(C.RESULT_BUFFER_READ);
    assertThat(inputBuffer.data.array()).isEqualTo(getEncodedMessage(eventMessage2));
}
Also used : EventMessage(com.google.android.exoplayer2.metadata.emsg.EventMessage) EventStream(com.google.android.exoplayer2.source.dash.manifest.EventStream) Test(org.junit.Test)

Aggregations

EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)16 Test (org.junit.Test)14 EventMessage (com.google.android.exoplayer2.metadata.emsg.EventMessage)12 Format (com.google.android.exoplayer2.Format)3 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)2 ArrayList (java.util.ArrayList)2 Pair (android.util.Pair)1 Nullable (androidx.annotation.Nullable)1 EmptySampleStream (com.google.android.exoplayer2.source.EmptySampleStream)1 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)1 ChunkSampleStream (com.google.android.exoplayer2.source.chunk.ChunkSampleStream)1 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)1 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1