From c66d26b6014be13cfa0cc4be35ebc6ae4f85eb00 Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 12 Feb 2019 09:18:08 +0000 Subject: [PATCH] Fix EventMessage timestamp issue Stop encoding/decoding presentation time as part of the message. What's actually in emsg boxes is a presentation time delta, which is why it's only 32 bits, and hence why it doesn't handle large absolute timestamps. We were using this field to hold absolute timestamps only for the purpose of passing presentation times from DashManifestParser.parseEvent back to the calling method. After this change, we return Pair instead. Issue: #5490 PiperOrigin-RevId: 233561731 --- RELEASENOTES.md | 3 + .../extractor/mp4/FragmentedMp4Extractor.java | 8 ++ .../metadata/emsg/EventMessage.java | 24 ++---- .../metadata/emsg/EventMessageDecoder.java | 22 ++++-- .../metadata/emsg/EventMessageEncoder.java | 20 ++--- .../emsg/EventMessageDecoderTest.java | 1 - .../emsg/EventMessageEncoderTest.java | 78 ++++++++++--------- .../metadata/emsg/EventMessageTest.java | 4 +- .../source/dash/EventSampleStream.java | 3 +- .../dash/manifest/DashManifestParser.java | 38 ++++----- .../source/dash/EventSampleStreamTest.java | 46 +++++------ .../dash/manifest/DashManifestParserTest.java | 75 +++++++++--------- 12 files changed, 164 insertions(+), 158 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 87b00b0e11..7a7decfbc0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,6 +8,9 @@ Cast demo app to work with `ExoCastPlayer`. * HLS: * Form an adaptive track group out of audio renditions with matching name. +* DASH: + * Fix issue handling large `EventStream` presentation timestamps + ([#5490](https://github.com/google/ExoPlayer/issues/5490)). * `ExtractorMediaSource` renamed to `ProgressiveMediaSource`. * Support for playing spherical videos on Daydream. * Improve decoder re-use between playbacks. TODO: Write and link a blog post diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 72bcaa9fe2..9ccb2556bc 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -601,6 +601,14 @@ public class FragmentedMp4Extractor implements Extractor { long presentationTimeDeltaUs = Util.scaleLargeTimestamp(atom.readUnsignedInt(), C.MICROS_PER_SECOND, timescale); + // The presentation_time_delta is accounted for by adjusting the sample timestamp, so we zero it + // in the sample data before writing it to the track outputs. + int position = atom.getPosition(); + atom.data[position - 4] = 0; + atom.data[position - 3] = 0; + atom.data[position - 2] = 0; + atom.data[position - 1] = 0; + // Output the sample data. for (TrackOutput emsgTrackOutput : emsgTrackOutputs) { atom.setPosition(Atom.FULL_HEADER_SIZE); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessage.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessage.java index 7d70d9de1c..8a3467e2ed 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessage.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessage.java @@ -44,13 +44,6 @@ public final class EventMessage implements Metadata.Entry { */ public final long durationMs; - /** - * The presentation time value of this event message in microseconds. - *

- * Except in special cases, application code should not use this field. - */ - public final long presentationTimeUs; - /** * The instance identifier. */ @@ -70,22 +63,19 @@ public final class EventMessage implements Metadata.Entry { * @param durationMs The duration of the event in milliseconds. * @param id The instance identifier. * @param messageData The body of the message. - * @param presentationTimeUs The presentation time value of this event message in microseconds. */ - public EventMessage(String schemeIdUri, String value, long durationMs, long id, - byte[] messageData, long presentationTimeUs) { + public EventMessage( + String schemeIdUri, String value, long durationMs, long id, byte[] messageData) { this.schemeIdUri = schemeIdUri; this.value = value; this.durationMs = durationMs; this.id = id; this.messageData = messageData; - this.presentationTimeUs = presentationTimeUs; } /* package */ EventMessage(Parcel in) { schemeIdUri = castNonNull(in.readString()); value = castNonNull(in.readString()); - presentationTimeUs = in.readLong(); durationMs = in.readLong(); id = in.readLong(); messageData = castNonNull(in.createByteArray()); @@ -97,7 +87,6 @@ public final class EventMessage implements Metadata.Entry { int result = 17; result = 31 * result + (schemeIdUri != null ? schemeIdUri.hashCode() : 0); result = 31 * result + (value != null ? value.hashCode() : 0); - result = 31 * result + (int) (presentationTimeUs ^ (presentationTimeUs >>> 32)); result = 31 * result + (int) (durationMs ^ (durationMs >>> 32)); result = 31 * result + (int) (id ^ (id >>> 32)); result = 31 * result + Arrays.hashCode(messageData); @@ -115,9 +104,11 @@ public final class EventMessage implements Metadata.Entry { return false; } EventMessage other = (EventMessage) obj; - return presentationTimeUs == other.presentationTimeUs && durationMs == other.durationMs - && id == other.id && Util.areEqual(schemeIdUri, other.schemeIdUri) - && Util.areEqual(value, other.value) && Arrays.equals(messageData, other.messageData); + return durationMs == other.durationMs + && id == other.id + && Util.areEqual(schemeIdUri, other.schemeIdUri) + && Util.areEqual(value, other.value) + && Arrays.equals(messageData, other.messageData); } @Override @@ -136,7 +127,6 @@ public final class EventMessage implements Metadata.Entry { public void writeToParcel(Parcel dest, int flags) { dest.writeString(schemeIdUri); dest.writeString(value); - dest.writeLong(presentationTimeUs); dest.writeLong(durationMs); dest.writeLong(id); dest.writeByteArray(messageData); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoder.java index 14f678374c..33d79917eb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoder.java @@ -15,11 +15,11 @@ */ package com.google.android.exoplayer2.metadata.emsg; -import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.MetadataDecoder; import com.google.android.exoplayer2.metadata.MetadataInputBuffer; import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; import java.nio.ByteBuffer; @@ -27,12 +27,15 @@ import java.util.Arrays; /** * Decodes Event Message (emsg) atoms, as defined in ISO/IEC 23009-1:2014, Section 5.10.3.3. - *

- * Atom data should be provided to the decoder without the full atom header (i.e. starting from the - * first byte of the scheme_id_uri field). + * + *

Atom data should be provided to the decoder without the full atom header (i.e. starting from + * the first byte of the scheme_id_uri field). It is expected that the presentation_time_delta field + * should be 0, having already been accounted for by adjusting the sample timestamp. */ public final class EventMessageDecoder implements MetadataDecoder { + private static final String TAG = "EventMessageDecoder"; + @SuppressWarnings("ByteBufferBackingArray") @Override public Metadata decode(MetadataInputBuffer inputBuffer) { @@ -43,13 +46,16 @@ public final class EventMessageDecoder implements MetadataDecoder { String schemeIdUri = Assertions.checkNotNull(emsgData.readNullTerminatedString()); String value = Assertions.checkNotNull(emsgData.readNullTerminatedString()); long timescale = emsgData.readUnsignedInt(); - long presentationTimeUs = Util.scaleLargeTimestamp(emsgData.readUnsignedInt(), - C.MICROS_PER_SECOND, timescale); + long presentationTimeDelta = emsgData.readUnsignedInt(); + if (presentationTimeDelta != 0) { + // We expect the source to have accounted for presentation_time_delta by adjusting the sample + // timestamp and zeroing the field in the sample data. Log a warning if the field is non-zero. + Log.w(TAG, "Ignoring non-zero presentation_time_delta: " + presentationTimeDelta); + } long durationMs = Util.scaleLargeTimestamp(emsgData.readUnsignedInt(), 1000, timescale); long id = emsgData.readUnsignedInt(); byte[] messageData = Arrays.copyOfRange(data, emsgData.getPosition(), size); - return new Metadata(new EventMessage(schemeIdUri, value, durationMs, id, messageData, - presentationTimeUs)); + return new Metadata(new EventMessage(schemeIdUri, value, durationMs, id, messageData)); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoder.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoder.java index eca498a6df..22708a8448 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoder.java @@ -16,9 +16,6 @@ package com.google.android.exoplayer2.metadata.emsg; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.util.Assertions; -import com.google.android.exoplayer2.util.Util; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -37,27 +34,22 @@ public final class EventMessageEncoder { } /** - * Encodes an {@link EventMessage} to a byte array that can be decoded by - * {@link EventMessageDecoder}. + * Encodes an {@link EventMessage} to a byte array that can be decoded by {@link + * EventMessageDecoder}. * * @param eventMessage The event message to be encoded. - * @param timescale Timescale of the event message, in units per second. * @return The serialized byte array. */ @Nullable - public byte[] encode(EventMessage eventMessage, long timescale) { - Assertions.checkArgument(timescale >= 0); + public byte[] encode(EventMessage eventMessage) { byteArrayOutputStream.reset(); try { writeNullTerminatedString(dataOutputStream, eventMessage.schemeIdUri); String nonNullValue = eventMessage.value != null ? eventMessage.value : ""; writeNullTerminatedString(dataOutputStream, nonNullValue); - writeUnsignedInt(dataOutputStream, timescale); - long presentationTime = Util.scaleLargeTimestamp(eventMessage.presentationTimeUs, - timescale, C.MICROS_PER_SECOND); - writeUnsignedInt(dataOutputStream, presentationTime); - long duration = Util.scaleLargeTimestamp(eventMessage.durationMs, timescale, 1000); - writeUnsignedInt(dataOutputStream, duration); + writeUnsignedInt(dataOutputStream, 1000); // timescale + writeUnsignedInt(dataOutputStream, 0); // presentation_time_delta + writeUnsignedInt(dataOutputStream, eventMessage.durationMs); writeUnsignedInt(dataOutputStream, eventMessage.id); dataOutputStream.write(eventMessage.messageData); dataOutputStream.flush(); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoderTest.java b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoderTest.java index c6558e3fc9..85d336b439 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoderTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageDecoderTest.java @@ -51,7 +51,6 @@ public final class EventMessageDecoderTest { assertThat(eventMessage.durationMs).isEqualTo(3000); assertThat(eventMessage.id).isEqualTo(1000403); assertThat(eventMessage.messageData).isEqualTo(new byte[]{0, 1, 2, 3, 4}); - assertThat(eventMessage.presentationTimeUs).isEqualTo(1000000); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoderTest.java b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoderTest.java index 7195548fbf..2869692272 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoderTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageEncoderTest.java @@ -33,25 +33,27 @@ public final class EventMessageEncoderTest { @Test public void testEncodeEventStream() throws IOException { - EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, - new byte[] {0, 1, 2, 3, 4}, 1000000); - byte[] expectedEmsgBody = new byte[] { - 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" - 49, 50, 51, 0, // value = "123" - 0, 0, -69, -128, // timescale = 48000 - 0, 0, -69, -128, // presentation_time_delta = 48000 - 0, 2, 50, -128, // event_duration = 144000 - 0, 15, 67, -45, // id = 1000403 - 0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4} - byte[] encodedByteArray = new EventMessageEncoder().encode(eventMessage, 48000); + EventMessage eventMessage = + new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4}); + byte[] expectedEmsgBody = + new byte[] { + 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" + 49, 50, 51, 0, // value = "123" + 0, 0, 3, -24, // timescale = 1000 + 0, 0, 0, 0, // presentation_time_delta = 0 + 0, 0, 11, -72, // event_duration = 3000 + 0, 15, 67, -45, // id = 1000403 + 0, 1, 2, 3, 4 + }; // message_data = {0, 1, 2, 3, 4} + byte[] encodedByteArray = new EventMessageEncoder().encode(eventMessage); assertThat(encodedByteArray).isEqualTo(expectedEmsgBody); } @Test public void testEncodeDecodeEventStream() throws IOException { - EventMessage expectedEmsg = new EventMessage("urn:test", "123", 3000, 1000403, - new byte[] {0, 1, 2, 3, 4}, 1000000); - byte[] encodedByteArray = new EventMessageEncoder().encode(expectedEmsg, 48000); + EventMessage expectedEmsg = + new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4}); + byte[] encodedByteArray = new EventMessageEncoder().encode(expectedEmsg); MetadataInputBuffer buffer = new MetadataInputBuffer(); buffer.data = ByteBuffer.allocate(encodedByteArray.length).put(encodedByteArray); @@ -63,30 +65,34 @@ public final class EventMessageEncoderTest { @Test public void testEncodeEventStreamMultipleTimesWorkingCorrectly() throws IOException { - EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, - new byte[] {0, 1, 2, 3, 4}, 1000000); - byte[] expectedEmsgBody = new byte[] { - 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" - 49, 50, 51, 0, // value = "123" - 0, 0, -69, -128, // timescale = 48000 - 0, 0, -69, -128, // presentation_time_delta = 48000 - 0, 2, 50, -128, // event_duration = 144000 - 0, 15, 67, -45, // id = 1000403 - 0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4} - EventMessage eventMessage1 = new EventMessage("urn:test", "123", 3000, 1000402, - new byte[] {4, 3, 2, 1, 0}, 1000000); - byte[] expectedEmsgBody1 = new byte[] { - 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" - 49, 50, 51, 0, // value = "123" - 0, 0, -69, -128, // timescale = 48000 - 0, 0, -69, -128, // presentation_time_delta = 48000 - 0, 2, 50, -128, // event_duration = 144000 - 0, 15, 67, -46, // id = 1000402 - 4, 3, 2, 1, 0}; // message_data = {4, 3, 2, 1, 0} + EventMessage eventMessage = + new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4}); + byte[] expectedEmsgBody = + new byte[] { + 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" + 49, 50, 51, 0, // value = "123" + 0, 0, 3, -24, // timescale = 1000 + 0, 0, 0, 0, // presentation_time_delta = 0 + 0, 0, 11, -72, // event_duration = 3000 + 0, 15, 67, -45, // id = 1000403 + 0, 1, 2, 3, 4 + }; // message_data = {0, 1, 2, 3, 4} + EventMessage eventMessage1 = + new EventMessage("urn:test", "123", 3000, 1000402, new byte[] {4, 3, 2, 1, 0}); + byte[] expectedEmsgBody1 = + new byte[] { + 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" + 49, 50, 51, 0, // value = "123" + 0, 0, 3, -24, // timescale = 1000 + 0, 0, 0, 0, // presentation_time_delta = 0 + 0, 0, 11, -72, // event_duration = 3000 + 0, 15, 67, -46, // id = 1000402 + 4, 3, 2, 1, 0 + }; // message_data = {4, 3, 2, 1, 0} EventMessageEncoder eventMessageEncoder = new EventMessageEncoder(); - byte[] encodedByteArray = eventMessageEncoder.encode(eventMessage, 48000); + byte[] encodedByteArray = eventMessageEncoder.encode(eventMessage); assertThat(encodedByteArray).isEqualTo(expectedEmsgBody); - byte[] encodedByteArray1 = eventMessageEncoder.encode(eventMessage1, 48000); + byte[] encodedByteArray1 = eventMessageEncoder.encode(eventMessage1); assertThat(encodedByteArray1).isEqualTo(expectedEmsgBody1); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageTest.java b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageTest.java index 30e1cd6c1f..f7970d1a16 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/metadata/emsg/EventMessageTest.java @@ -30,8 +30,8 @@ public final class EventMessageTest { @Test public void testEventMessageParcelable() { - EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, - new byte[] {0, 1, 2, 3, 4}, 1000); + EventMessage eventMessage = + new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4}); // Write to parcel. Parcel parcel = Parcel.obtain(); eventMessage.writeToParcel(parcel, 0); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java index 9f812b8e84..f06a709960 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java @@ -112,8 +112,7 @@ import java.io.IOException; } } int sampleIndex = currentIndex++; - byte[] serializedEvent = eventMessageEncoder.encode(eventStream.events[sampleIndex], - eventStream.timescale); + byte[] serializedEvent = eventMessageEncoder.encode(eventStream.events[sampleIndex]); if (serializedEvent != null) { buffer.ensureSpaceForWrite(serializedEvent.length); buffer.setFlags(C.BUFFER_FLAG_KEY_FRAME); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index c501172dd4..c0aa2a7819 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -829,13 +829,13 @@ public class DashManifestParser extends DefaultHandler String schemeIdUri = parseString(xpp, "schemeIdUri", ""); String value = parseString(xpp, "value", ""); long timescale = parseLong(xpp, "timescale", 1); - List eventMessages = new ArrayList<>(); + List> eventMessages = new ArrayList<>(); ByteArrayOutputStream scratchOutputStream = new ByteArrayOutputStream(512); do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Event")) { - EventMessage event = parseEvent(xpp, schemeIdUri, value, timescale, - scratchOutputStream); + Pair event = + parseEvent(xpp, schemeIdUri, value, timescale, scratchOutputStream); eventMessages.add(event); } else { maybeSkipTag(xpp); @@ -845,9 +845,9 @@ public class DashManifestParser extends DefaultHandler long[] presentationTimesUs = new long[eventMessages.size()]; EventMessage[] events = new EventMessage[eventMessages.size()]; for (int i = 0; i < eventMessages.size(); i++) { - EventMessage event = eventMessages.get(i); - presentationTimesUs[i] = event.presentationTimeUs; - events[i] = event; + Pair event = eventMessages.get(i); + presentationTimesUs[i] = event.first; + events[i] = event.second; } return buildEventStream(schemeIdUri, value, timescale, presentationTimesUs, events); } @@ -866,11 +866,12 @@ public class DashManifestParser extends DefaultHandler * @param timescale The timescale of the parent EventStream. * @param scratchOutputStream A {@link ByteArrayOutputStream} that is used when parsing event * objects. - * @return The {@link EventMessage} parsed from this EventStream node. + * @return A pair containing the node's presentation timestamp in microseconds and the parsed + * {@link EventMessage}. * @throws XmlPullParserException If there is any error parsing this node. * @throws IOException If there is any error reading from the underlying input stream. */ - protected EventMessage parseEvent( + protected Pair parseEvent( XmlPullParser xpp, String schemeIdUri, String value, @@ -885,13 +886,14 @@ public class DashManifestParser extends DefaultHandler timescale); String messageData = parseString(xpp, "messageData", null); byte[] eventObject = parseEventObject(xpp, scratchOutputStream); - return buildEvent( - schemeIdUri, - value, - id, - durationMs, - messageData == null ? eventObject : Util.getUtf8Bytes(messageData), - presentationTimesUs); + return Pair.create( + presentationTimesUs, + buildEvent( + schemeIdUri, + value, + id, + durationMs, + messageData == null ? eventObject : Util.getUtf8Bytes(messageData))); } /** @@ -958,9 +960,9 @@ public class DashManifestParser extends DefaultHandler return scratchOutputStream.toByteArray(); } - protected EventMessage buildEvent(String schemeIdUri, String value, long id, - long durationMs, byte[] messageData, long presentationTimeUs) { - return new EventMessage(schemeIdUri, value, durationMs, id, messageData, presentationTimeUs); + protected EventMessage buildEvent( + String schemeIdUri, String value, long id, long durationMs, byte[] messageData) { + return new EventMessage(schemeIdUri, value, durationMs, id, messageData); } protected List parseSegmentTimeline(XmlPullParser xpp) diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java index 9c3752551a..9621381eed 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java @@ -111,7 +111,7 @@ public final class EventSampleStreamTest { @Test public void testReadDataReturnDataAfterFormat() { long presentationTimeUs = 1000000; - EventMessage eventMessage = newEventMessageWithIdAndTime(1, presentationTimeUs); + EventMessage eventMessage = newEventMessageWithId(1); EventStream eventStream = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] {presentationTimeUs}, new EventMessage[] {eventMessage}); EventSampleStream sampleStream = new EventSampleStream(eventStream, FORMAT, false); @@ -133,8 +133,8 @@ public final class EventSampleStreamTest { public void testSkipDataThenReadDataReturnDataFromSkippedPosition() { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); + 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}); @@ -159,8 +159,8 @@ public final class EventSampleStreamTest { public void testSeekToUsThenReadDataReturnDataFromSeekPosition() { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); + 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}); @@ -186,9 +186,9 @@ public final class EventSampleStreamTest { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; long presentationTimeUs3 = 3000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); - EventMessage eventMessage3 = newEventMessageWithIdAndTime(3, presentationTimeUs3); + 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}); @@ -220,9 +220,9 @@ public final class EventSampleStreamTest { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; long presentationTimeUs3 = 3000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); - EventMessage eventMessage3 = newEventMessageWithIdAndTime(3, presentationTimeUs3); + 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}); @@ -253,9 +253,9 @@ public final class EventSampleStreamTest { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; long presentationTimeUs3 = 3000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); - EventMessage eventMessage3 = newEventMessageWithIdAndTime(3, presentationTimeUs3); + EventMessage eventMessage1 = newEventMessageWithId(1); + EventMessage eventMessage2 = newEventMessageWithId(2); + EventMessage eventMessage3 = newEventMessageWithId(3); EventStream eventStream1 = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] {presentationTimeUs1}, new EventMessage[] {eventMessage1}); @@ -287,9 +287,9 @@ public final class EventSampleStreamTest { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; long presentationTimeUs3 = 3000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); - EventMessage eventMessage3 = newEventMessageWithIdAndTime(3, presentationTimeUs3); + 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}); @@ -319,9 +319,9 @@ public final class EventSampleStreamTest { long presentationTimeUs1 = 1000000; long presentationTimeUs2 = 2000000; long presentationTimeUs3 = 3000000; - EventMessage eventMessage1 = newEventMessageWithIdAndTime(1, presentationTimeUs1); - EventMessage eventMessage2 = newEventMessageWithIdAndTime(2, presentationTimeUs2); - EventMessage eventMessage3 = newEventMessageWithIdAndTime(3, presentationTimeUs3); + EventMessage eventMessage1 = newEventMessageWithId(1); + EventMessage eventMessage2 = newEventMessageWithId(2); + EventMessage eventMessage3 = newEventMessageWithId(3); EventStream eventStream1 = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[] {presentationTimeUs1}, new EventMessage[] {eventMessage1}); @@ -345,12 +345,12 @@ public final class EventSampleStreamTest { return sampleStream.readData(formatHolder, inputBuffer, false); } - private EventMessage newEventMessageWithIdAndTime(int id, long presentationTimeUs) { - return new EventMessage(SCHEME_ID, VALUE, DURATION_MS, id, MESSAGE_DATA, presentationTimeUs); + private EventMessage newEventMessageWithId(int id) { + return new EventMessage(SCHEME_ID, VALUE, DURATION_MS, id, MESSAGE_DATA); } private byte[] getEncodedMessage(EventMessage eventMessage) { - return eventMessageEncoder.encode(eventMessage, TIME_SCALE); + return eventMessageEncoder.encode(eventMessage); } } diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java index a1693f6985..67d8dbecac 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java @@ -104,52 +104,53 @@ public class DashManifestParserTest { "call", 10000, 0, - "+ 1 800 10101010".getBytes(Charset.forName(C.UTF8_NAME)), - 0); + "+ 1 800 10101010".getBytes(Charset.forName(C.UTF8_NAME))); assertThat(eventStream1.events[0]).isEqualTo(expectedEvent1); + assertThat(eventStream1.presentationTimesUs[0]).isEqualTo(0); // assert CData-structured event stream EventStream eventStream2 = period.eventStreams.get(1); assertThat(eventStream2.events.length).isEqualTo(1); - assertThat(eventStream2.events[0]) - .isEqualTo( - new EventMessage( - "urn:dvb:iptv:cpm:2014", - "", - 1500000, - 1, - Util.getUtf8Bytes( - "\n" - + " \n" - + " \n" - + " The title\n" - + " " - + "The description\n" - + " \n" - + " \n" - + " GB\n" - + " \n" - + " \n" - + " ]]>"), - 300000000)); + EventMessage expectedEvent2 = + new EventMessage( + "urn:dvb:iptv:cpm:2014", + "", + 1500000, + 1, + Util.getUtf8Bytes( + "\n" + + " \n" + + " \n" + + " The title\n" + + " " + + "The description\n" + + " \n" + + " \n" + + " GB\n" + + " \n" + + " \n" + + " ]]>")); + + assertThat(eventStream2.events[0]).isEqualTo(expectedEvent2); + assertThat(eventStream2.presentationTimesUs[0]).isEqualTo(300000000); // assert xml-structured event stream EventStream eventStream3 = period.eventStreams.get(2); assertThat(eventStream3.events.length).isEqualTo(1); - assertThat(eventStream3.events[0]) - .isEqualTo( - new EventMessage( - "urn:scte:scte35:2014:xml+bin", - "", - 1000000, - 2, - Util.getUtf8Bytes( - "\n" - + " \n" - + " /DAIAAAAAAAAAAAQAAZ/I0VniQAQAgBDVUVJQAAAAH+cAAAAAA==\n" - + " \n" - + " "), - 1000000000)); + EventMessage expectedEvent3 = + new EventMessage( + "urn:scte:scte35:2014:xml+bin", + "", + 1000000, + 2, + Util.getUtf8Bytes( + "\n" + + " \n" + + " /DAIAAAAAAAAAAAQAAZ/I0VniQAQAgBDVUVJQAAAAH+cAAAAAA==\n" + + " \n" + + " ")); + assertThat(eventStream3.events[0]).isEqualTo(expectedEvent3); + assertThat(eventStream3.presentationTimesUs[0]).isEqualTo(1000000000); } @Test