Search in sources :

Example 6 with EventStream

use of androidx.media3.exoplayer.dash.manifest.EventStream in project media by androidx.

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(androidx.media3.extractor.metadata.emsg.EventMessage) EventStream(androidx.media3.exoplayer.dash.manifest.EventStream) Test(org.junit.Test)

Example 7 with EventStream

use of androidx.media3.exoplayer.dash.manifest.EventStream in project media by androidx.

the class EventSampleStreamTest method skipDataThenUpdateStreamContinueToReadFromSkippedPosition.

/**
 * Tests that {@link EventSampleStream#updateEventStream(EventStream, boolean)} will update the
 * underlying event stream, but keep the timestamp the stream has skipped to, so the next {@link
 * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return sample data
 * from the skipped position.
 */
@Test
public void skipDataThenUpdateStreamContinueToReadFromSkippedPosition() {
    long presentationTimeUs1 = 1000000;
    long presentationTimeUs2 = 2000000;
    long presentationTimeUs3 = 3000000;
    EventMessage eventMessage1 = newEventMessageWithId(1);
    EventMessage eventMessage2 = newEventMessageWithId(2);
    EventMessage eventMessage3 = newEventMessageWithId(3);
    EventStream eventStream1 = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] { presentationTimeUs1, presentationTimeUs2 }, new EventMessage[] { eventMessage1, eventMessage2 });
    EventStream eventStream2 = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] { presentationTimeUs1, presentationTimeUs2, presentationTimeUs3 }, new EventMessage[] { eventMessage1, eventMessage2, eventMessage3 });
    EventSampleStream sampleStream = new EventSampleStream(eventStream1, FORMAT, true);
    // first read - read format
    readData(sampleStream);
    sampleStream.skipData(presentationTimeUs2 + 1);
    sampleStream.updateEventStream(eventStream2, true);
    int result = readData(sampleStream);
    assertThat(result).isEqualTo(C.RESULT_BUFFER_READ);
    assertThat(inputBuffer.data.array()).isEqualTo(getEncodedMessage(eventMessage3));
}
Also used : EventMessage(androidx.media3.extractor.metadata.emsg.EventMessage) EventStream(androidx.media3.exoplayer.dash.manifest.EventStream) Test(org.junit.Test)

Example 8 with EventStream

use of androidx.media3.exoplayer.dash.manifest.EventStream in project media by androidx.

the class DashManifestParser method parseEventStream.

/**
 * Parses a single EventStream node in the manifest.
 *
 * @param xpp The current xml parser.
 * @return The {@link EventStream} parsed from this EventStream node.
 * @throws XmlPullParserException If there is any error parsing this node.
 * @throws IOException If there is any error reading from the underlying input stream.
 */
protected EventStream parseEventStream(XmlPullParser xpp) throws XmlPullParserException, IOException {
    String schemeIdUri = parseString(xpp, "schemeIdUri", "");
    String value = parseString(xpp, "value", "");
    long timescale = parseLong(xpp, "timescale", 1);
    List<Pair<Long, EventMessage>> eventMessages = new ArrayList<>();
    ByteArrayOutputStream scratchOutputStream = new ByteArrayOutputStream(512);
    do {
        xpp.next();
        if (XmlPullParserUtil.isStartTag(xpp, "Event")) {
            Pair<Long, EventMessage> event = parseEvent(xpp, schemeIdUri, value, timescale, scratchOutputStream);
            eventMessages.add(event);
        } else {
            maybeSkipTag(xpp);
        }
    } while (!XmlPullParserUtil.isEndTag(xpp, "EventStream"));
    long[] presentationTimesUs = new long[eventMessages.size()];
    EventMessage[] events = new EventMessage[eventMessages.size()];
    for (int i = 0; i < eventMessages.size(); i++) {
        Pair<Long, EventMessage> event = eventMessages.get(i);
        presentationTimesUs[i] = event.first;
        events[i] = event.second;
    }
    return buildEventStream(schemeIdUri, value, timescale, presentationTimesUs, events);
}
Also used : EventMessage(androidx.media3.extractor.metadata.emsg.EventMessage) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Pair(android.util.Pair)

Example 9 with EventStream

use of androidx.media3.exoplayer.dash.manifest.EventStream in project media by androidx.

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(androidx.media3.exoplayer.dash.manifest.SegmentBase.SingleSegmentBase) Nullable(androidx.annotation.Nullable)

Example 10 with EventStream

use of androidx.media3.exoplayer.dash.manifest.EventStream in project media by androidx.

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(androidx.media3.common.Format) TrackGroup(androidx.media3.common.TrackGroup) TrackGroupArray(androidx.media3.common.TrackGroupArray)

Aggregations

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