Let EventMessage encloses its presentationTimeMs.

Currently EventMessage's presentationTimeMs is kept separately in
EventSampleStream. However, EventMessage's presentationTimeMs maybe used in
other places besides EventSampleStream, such as when handling `emsg' messages
targeting the player. This CL let EventMessage object to holds its
presentationTimeMs for such use cases.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176502938
This commit is contained in:
hoangtc 2017-11-21 07:03:55 -08:00 committed by Oliver Woodman
parent 3998ed49ae
commit e619079a0d
9 changed files with 57 additions and 44 deletions

View file

@ -41,6 +41,13 @@ public final class EventMessage implements Metadata.Entry {
*/ */
public final long durationMs; public final long durationMs;
/**
* The presentation time value of this event message in microseconds.
* <p>
* Except in special cases, application code should <em>not</em> use this field.
*/
public final long presentationTimeUs;
/** /**
* The instance identifier. * The instance identifier.
*/ */
@ -55,25 +62,27 @@ public final class EventMessage implements Metadata.Entry {
private int hashCode; private int hashCode;
/** /**
*
* @param schemeIdUri The message scheme. * @param schemeIdUri The message scheme.
* @param value The value for the event. * @param value The value for the event.
* @param durationMs The duration of the event in milliseconds. * @param durationMs The duration of the event in milliseconds.
* @param id The instance identifier. * @param id The instance identifier.
* @param messageData The body of the message. * @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, public EventMessage(String schemeIdUri, String value, long durationMs, long id,
byte[] messageData) { byte[] messageData, long presentationTimeUs) {
this.schemeIdUri = schemeIdUri; this.schemeIdUri = schemeIdUri;
this.value = value; this.value = value;
this.durationMs = durationMs; this.durationMs = durationMs;
this.id = id; this.id = id;
this.messageData = messageData; this.messageData = messageData;
this.presentationTimeUs = presentationTimeUs;
} }
/* package */ EventMessage(Parcel in) { /* package */ EventMessage(Parcel in) {
schemeIdUri = in.readString(); schemeIdUri = in.readString();
value = in.readString(); value = in.readString();
presentationTimeUs = in.readLong();
durationMs = in.readLong(); durationMs = in.readLong();
id = in.readLong(); id = in.readLong();
messageData = in.createByteArray(); messageData = in.createByteArray();
@ -85,6 +94,7 @@ public final class EventMessage implements Metadata.Entry {
int result = 17; int result = 17;
result = 31 * result + (schemeIdUri != null ? schemeIdUri.hashCode() : 0); result = 31 * result + (schemeIdUri != null ? schemeIdUri.hashCode() : 0);
result = 31 * result + (value != null ? value.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) (durationMs ^ (durationMs >>> 32));
result = 31 * result + (int) (id ^ (id >>> 32)); result = 31 * result + (int) (id ^ (id >>> 32));
result = 31 * result + Arrays.hashCode(messageData); result = 31 * result + Arrays.hashCode(messageData);
@ -102,9 +112,9 @@ public final class EventMessage implements Metadata.Entry {
return false; return false;
} }
EventMessage other = (EventMessage) obj; EventMessage other = (EventMessage) obj;
return durationMs == other.durationMs && id == other.id return presentationTimeUs == other.presentationTimeUs && durationMs == other.durationMs
&& Util.areEqual(schemeIdUri, other.schemeIdUri) && Util.areEqual(value, other.value) && id == other.id && Util.areEqual(schemeIdUri, other.schemeIdUri)
&& Arrays.equals(messageData, other.messageData); && Util.areEqual(value, other.value) && Arrays.equals(messageData, other.messageData);
} }
// Parcelable implementation. // Parcelable implementation.
@ -118,6 +128,7 @@ public final class EventMessage implements Metadata.Entry {
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeString(schemeIdUri); dest.writeString(schemeIdUri);
dest.writeString(value); dest.writeString(value);
dest.writeLong(presentationTimeUs);
dest.writeLong(durationMs); dest.writeLong(durationMs);
dest.writeLong(id); dest.writeLong(id);
dest.writeByteArray(messageData); dest.writeByteArray(messageData);

View file

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.metadata.emsg; 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.Metadata;
import com.google.android.exoplayer2.metadata.MetadataDecoder; import com.google.android.exoplayer2.metadata.MetadataDecoder;
import com.google.android.exoplayer2.metadata.MetadataInputBuffer; import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
@ -24,7 +25,7 @@ import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Decodes Event Message (emsg) atoms, as defined in ISO 23009-1. * Decodes Event Message (emsg) atoms, as defined in ISO/IEC 23009-1:2014, Section 5.10.3.3.
* <p> * <p>
* Atom data should be provided to the decoder without the full atom header (i.e. starting from the * 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). * first byte of the scheme_id_uri field).
@ -40,11 +41,13 @@ public final class EventMessageDecoder implements MetadataDecoder {
String schemeIdUri = emsgData.readNullTerminatedString(); String schemeIdUri = emsgData.readNullTerminatedString();
String value = emsgData.readNullTerminatedString(); String value = emsgData.readNullTerminatedString();
long timescale = emsgData.readUnsignedInt(); long timescale = emsgData.readUnsignedInt();
emsgData.skipBytes(4); // presentation_time_delta long presentationTimeUs = Util.scaleLargeTimestamp(emsgData.readUnsignedInt(),
C.MICROS_PER_SECOND, timescale);
long durationMs = Util.scaleLargeTimestamp(emsgData.readUnsignedInt(), 1000, timescale); long durationMs = Util.scaleLargeTimestamp(emsgData.readUnsignedInt(), 1000, timescale);
long id = emsgData.readUnsignedInt(); long id = emsgData.readUnsignedInt();
byte[] messageData = Arrays.copyOfRange(data, emsgData.getPosition(), size); byte[] messageData = Arrays.copyOfRange(data, emsgData.getPosition(), size);
return new Metadata(new EventMessage(schemeIdUri, value, durationMs, id, messageData)); return new Metadata(new EventMessage(schemeIdUri, value, durationMs, id, messageData,
presentationTimeUs));
} }
} }

View file

@ -42,11 +42,10 @@ public final class EventMessageEncoder {
* *
* @param eventMessage The event message to be encoded. * @param eventMessage The event message to be encoded.
* @param timescale Timescale of the event message, in units per second. * @param timescale Timescale of the event message, in units per second.
* @param presentationTimeUs The presentation time of the event message in microseconds.
* @return The serialized byte array. * @return The serialized byte array.
*/ */
@Nullable @Nullable
public byte[] encode(EventMessage eventMessage, long timescale, long presentationTimeUs) { public byte[] encode(EventMessage eventMessage, long timescale) {
Assertions.checkArgument(timescale >= 0); Assertions.checkArgument(timescale >= 0);
byteArrayOutputStream.reset(); byteArrayOutputStream.reset();
try { try {
@ -54,8 +53,8 @@ public final class EventMessageEncoder {
String nonNullValue = eventMessage.value != null ? eventMessage.value : ""; String nonNullValue = eventMessage.value != null ? eventMessage.value : "";
writeNullTerminatedString(dataOutputStream, nonNullValue); writeNullTerminatedString(dataOutputStream, nonNullValue);
writeUnsignedInt(dataOutputStream, timescale); writeUnsignedInt(dataOutputStream, timescale);
long presentationTime = Util.scaleLargeTimestamp(presentationTimeUs, timescale, long presentationTime = Util.scaleLargeTimestamp(eventMessage.presentationTimeUs,
C.MICROS_PER_SECOND); timescale, C.MICROS_PER_SECOND);
writeUnsignedInt(dataOutputStream, presentationTime); writeUnsignedInt(dataOutputStream, presentationTime);
long duration = Util.scaleLargeTimestamp(eventMessage.durationMs, timescale, 1000); long duration = Util.scaleLargeTimestamp(eventMessage.durationMs, timescale, 1000);
writeUnsignedInt(dataOutputStream, duration); writeUnsignedInt(dataOutputStream, duration);

View file

@ -38,7 +38,7 @@ public final class EventMessageDecoderTest {
117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test"
49, 50, 51, 0, // value = "123" 49, 50, 51, 0, // value = "123"
0, 0, -69, -128, // timescale = 48000 0, 0, -69, -128, // timescale = 48000
0, 0, 0, 0, // presentation_time_delta (ignored) = 0 0, 0, -69, -128, // presentation_time_delta = 48000
0, 2, 50, -128, // event_duration = 144000 0, 2, 50, -128, // event_duration = 144000
0, 15, 67, -45, // id = 1000403 0, 15, 67, -45, // id = 1000403
0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4} 0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4}
@ -53,6 +53,7 @@ public final class EventMessageDecoderTest {
assertThat(eventMessage.durationMs).isEqualTo(3000); assertThat(eventMessage.durationMs).isEqualTo(3000);
assertThat(eventMessage.id).isEqualTo(1000403); assertThat(eventMessage.id).isEqualTo(1000403);
assertThat(eventMessage.messageData).isEqualTo(new byte[]{0, 1, 2, 3, 4}); assertThat(eventMessage.messageData).isEqualTo(new byte[]{0, 1, 2, 3, 4});
assertThat(eventMessage.presentationTimeUs).isEqualTo(1000000);
} }
} }

View file

@ -36,24 +36,24 @@ public final class EventMessageEncoderTest {
@Test @Test
public void testEncodeEventStream() throws IOException { public void testEncodeEventStream() throws IOException {
EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403,
new byte[] {0, 1, 2, 3, 4}); new byte[] {0, 1, 2, 3, 4}, 1000000);
byte[] expectedEmsgBody = new byte[] { byte[] expectedEmsgBody = new byte[] {
117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test"
49, 50, 51, 0, // value = "123" 49, 50, 51, 0, // value = "123"
0, 0, -69, -128, // timescale = 48000 0, 0, -69, -128, // timescale = 48000
0, 0, -69, -128, // presentation_time_delta = 48 0, 0, -69, -128, // presentation_time_delta = 48000
0, 2, 50, -128, // event_duration = 144000 0, 2, 50, -128, // event_duration = 144000
0, 15, 67, -45, // id = 1000403 0, 15, 67, -45, // id = 1000403
0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4} 0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4}
byte[] encodedByteArray = new EventMessageEncoder().encode(eventMessage, 48000, 1000000); byte[] encodedByteArray = new EventMessageEncoder().encode(eventMessage, 48000);
assertThat(encodedByteArray).isEqualTo(expectedEmsgBody); assertThat(encodedByteArray).isEqualTo(expectedEmsgBody);
} }
@Test @Test
public void testEncodeDecodeEventStream() throws IOException { public void testEncodeDecodeEventStream() throws IOException {
EventMessage expectedEmsg = new EventMessage("urn:test", "123", 3000, 1000403, EventMessage expectedEmsg = new EventMessage("urn:test", "123", 3000, 1000403,
new byte[] {0, 1, 2, 3, 4}); new byte[] {0, 1, 2, 3, 4}, 1000000);
byte[] encodedByteArray = new EventMessageEncoder().encode(expectedEmsg, 48000, 1); byte[] encodedByteArray = new EventMessageEncoder().encode(expectedEmsg, 48000);
MetadataInputBuffer buffer = new MetadataInputBuffer(); MetadataInputBuffer buffer = new MetadataInputBuffer();
buffer.data = ByteBuffer.allocate(encodedByteArray.length).put(encodedByteArray); buffer.data = ByteBuffer.allocate(encodedByteArray.length).put(encodedByteArray);
@ -66,29 +66,29 @@ public final class EventMessageEncoderTest {
@Test @Test
public void testEncodeEventStreamMultipleTimesWorkingCorrectly() throws IOException { public void testEncodeEventStreamMultipleTimesWorkingCorrectly() throws IOException {
EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403,
new byte[] {0, 1, 2, 3, 4}); new byte[] {0, 1, 2, 3, 4}, 1000000);
byte[] expectedEmsgBody = new byte[] { byte[] expectedEmsgBody = new byte[] {
117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test"
49, 50, 51, 0, // value = "123" 49, 50, 51, 0, // value = "123"
0, 0, -69, -128, // timescale = 48000 0, 0, -69, -128, // timescale = 48000
0, 0, -69, -128, // presentation_time_delta = 48 0, 0, -69, -128, // presentation_time_delta = 48000
0, 2, 50, -128, // event_duration = 144000 0, 2, 50, -128, // event_duration = 144000
0, 15, 67, -45, // id = 1000403 0, 15, 67, -45, // id = 1000403
0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4} 0, 1, 2, 3, 4}; // message_data = {0, 1, 2, 3, 4}
EventMessage eventMessage1 = new EventMessage("urn:test", "123", 3000, 1000402, EventMessage eventMessage1 = new EventMessage("urn:test", "123", 3000, 1000402,
new byte[] {4, 3, 2, 1, 0}); new byte[] {4, 3, 2, 1, 0}, 1000000);
byte[] expectedEmsgBody1 = new byte[] { byte[] expectedEmsgBody1 = new byte[] {
117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test"
49, 50, 51, 0, // value = "123" 49, 50, 51, 0, // value = "123"
0, 0, -69, -128, // timescale = 48000 0, 0, -69, -128, // timescale = 48000
0, 0, -69, -128, // presentation_time_delta = 48 0, 0, -69, -128, // presentation_time_delta = 48000
0, 2, 50, -128, // event_duration = 144000 0, 2, 50, -128, // event_duration = 144000
0, 15, 67, -46, // id = 1000402 0, 15, 67, -46, // id = 1000402
4, 3, 2, 1, 0}; // message_data = {4, 3, 2, 1, 0} 4, 3, 2, 1, 0}; // message_data = {4, 3, 2, 1, 0}
EventMessageEncoder eventMessageEncoder = new EventMessageEncoder(); EventMessageEncoder eventMessageEncoder = new EventMessageEncoder();
byte[] encodedByteArray = eventMessageEncoder.encode(eventMessage, 48000, 1000000); byte[] encodedByteArray = eventMessageEncoder.encode(eventMessage, 48000);
assertThat(encodedByteArray).isEqualTo(expectedEmsgBody); assertThat(encodedByteArray).isEqualTo(expectedEmsgBody);
byte[] encodedByteArray1 = eventMessageEncoder.encode(eventMessage1, 48000, 1000000); byte[] encodedByteArray1 = eventMessageEncoder.encode(eventMessage1, 48000);
assertThat(encodedByteArray1).isEqualTo(expectedEmsgBody1); assertThat(encodedByteArray1).isEqualTo(expectedEmsgBody1);
} }

View file

@ -33,7 +33,7 @@ public final class EventMessageTest {
@Test @Test
public void testEventMessageParcelable() { public void testEventMessageParcelable() {
EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403,
new byte[] {0, 1, 2, 3, 4}); new byte[] {0, 1, 2, 3, 4}, 1000);
// Write to parcel. // Write to parcel.
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
eventMessage.writeToParcel(parcel, 0); eventMessage.writeToParcel(parcel, 0);

View file

@ -84,7 +84,7 @@ public class DashManifestParserTest extends InstrumentationTestCase {
EventStream eventStream1 = period.eventStreams.get(0); EventStream eventStream1 = period.eventStreams.get(0);
assertEquals(1, eventStream1.events.length); assertEquals(1, eventStream1.events.length);
EventMessage expectedEvent1 = new EventMessage("urn:uuid:XYZY", "call", 10000, 0, EventMessage expectedEvent1 = new EventMessage("urn:uuid:XYZY", "call", 10000, 0,
"+ 1 800 10101010".getBytes()); "+ 1 800 10101010".getBytes(), 0);
assertEquals(expectedEvent1, eventStream1.events[0]); assertEquals(expectedEvent1, eventStream1.events[0]);
// assert CData-structured event stream // assert CData-structured event stream
@ -102,7 +102,7 @@ public class DashManifestParserTest extends InstrumentationTestCase {
+ " <mpeg7:Region>GB</mpeg7:Region>\n" + " <mpeg7:Region>GB</mpeg7:Region>\n"
+ " </ParentalGuidance>\n" + " </ParentalGuidance>\n"
+ " </InstanceDescription>\n" + " </InstanceDescription>\n"
+ " </BroadcastEvent>]]>").getBytes()), + " </BroadcastEvent>]]>").getBytes(), 300000000),
eventStream2.events[0]); eventStream2.events[0]);
// assert xml-structured event stream // assert xml-structured event stream
@ -114,7 +114,7 @@ public class DashManifestParserTest extends InstrumentationTestCase {
+ " <scte35:Binary>\n" + " <scte35:Binary>\n"
+ " /DAIAAAAAAAAAAAQAAZ/I0VniQAQAgBDVUVJQAAAAH+cAAAAAA==\n" + " /DAIAAAAAAAAAAAQAAZ/I0VniQAQAgBDVUVJQAAAAH+cAAAAAA==\n"
+ " </scte35:Binary>\n" + " </scte35:Binary>\n"
+ " </scte35:Signal>").getBytes()), + " </scte35:Signal>").getBytes(), 1000000000),
eventStream3.events[0]); eventStream3.events[0]);
} }

View file

@ -95,7 +95,7 @@ import java.io.IOException;
} }
int sampleIndex = currentIndex++; int sampleIndex = currentIndex++;
byte[] serializedEvent = eventMessageEncoder.encode(eventStream.events[sampleIndex], byte[] serializedEvent = eventMessageEncoder.encode(eventStream.events[sampleIndex],
eventStream.timescale, eventTimesUs[sampleIndex]); eventStream.timescale);
if (serializedEvent != null) { if (serializedEvent != null) {
buffer.ensureSpaceForWrite(serializedEvent.length); buffer.ensureSpaceForWrite(serializedEvent.length);
buffer.setFlags(C.BUFFER_FLAG_KEY_FRAME); buffer.setFlags(C.BUFFER_FLAG_KEY_FRAME);

View file

@ -688,23 +688,23 @@ public class DashManifestParser extends DefaultHandler
String schemeIdUri = parseString(xpp, "schemeIdUri", ""); String schemeIdUri = parseString(xpp, "schemeIdUri", "");
String value = parseString(xpp, "value", ""); String value = parseString(xpp, "value", "");
long timescale = parseLong(xpp, "timescale", 1); long timescale = parseLong(xpp, "timescale", 1);
List<Pair<Long, EventMessage>> timedEvents = new ArrayList<>(); List<EventMessage> eventMessages = new ArrayList<>();
ByteArrayOutputStream scratchOutputStream = new ByteArrayOutputStream(512); ByteArrayOutputStream scratchOutputStream = new ByteArrayOutputStream(512);
do { do {
xpp.next(); xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "Event")) { if (XmlPullParserUtil.isStartTag(xpp, "Event")) {
Pair<Long, EventMessage> timedEvent = parseEvent(xpp, schemeIdUri, value, timescale, EventMessage event = parseEvent(xpp, schemeIdUri, value, timescale,
scratchOutputStream); scratchOutputStream);
timedEvents.add(timedEvent); eventMessages.add(event);
} }
} while (!XmlPullParserUtil.isEndTag(xpp, "EventStream")); } while (!XmlPullParserUtil.isEndTag(xpp, "EventStream"));
long[] presentationTimesUs = new long[timedEvents.size()]; long[] presentationTimesUs = new long[eventMessages.size()];
EventMessage[] events = new EventMessage[timedEvents.size()]; EventMessage[] events = new EventMessage[eventMessages.size()];
for (int i = 0; i < timedEvents.size(); i++) { for (int i = 0; i < eventMessages.size(); i++) {
Pair<Long, EventMessage> timedEvent = timedEvents.get(i); EventMessage event = eventMessages.get(i);
presentationTimesUs[i] = timedEvent.first; presentationTimesUs[i] = event.presentationTimeUs;
events[i] = timedEvent.second; events[i] = event;
} }
return buildEventStream(schemeIdUri, value, timescale, presentationTimesUs, events); return buildEventStream(schemeIdUri, value, timescale, presentationTimesUs, events);
} }
@ -723,11 +723,11 @@ public class DashManifestParser extends DefaultHandler
* @param timescale The timescale of the parent EventStream. * @param timescale The timescale of the parent EventStream.
* @param scratchOutputStream A {@link ByteArrayOutputStream} that is used to write serialize data * @param scratchOutputStream A {@link ByteArrayOutputStream} that is used to write serialize data
* in between <Event> and </Event> tags into. * in between <Event> and </Event> tags into.
* @return The {@link EventStream} parsed from this EventStream node. * @return The {@link EventMessage} parsed from this EventStream node.
* @throws XmlPullParserException If there is any error parsing this node. * @throws XmlPullParserException If there is any error parsing this node.
* @throws IOException If there is any error reading from the underlying input stream. * @throws IOException If there is any error reading from the underlying input stream.
*/ */
protected Pair<Long, EventMessage> parseEvent(XmlPullParser xpp, String schemeIdUri, String value, protected EventMessage parseEvent(XmlPullParser xpp, String schemeIdUri, String value,
long timescale, ByteArrayOutputStream scratchOutputStream) long timescale, ByteArrayOutputStream scratchOutputStream)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
long id = parseLong(xpp, "id", 0); long id = parseLong(xpp, "id", 0);
@ -737,8 +737,7 @@ public class DashManifestParser extends DefaultHandler
long presentationTimesUs = Util.scaleLargeTimestamp(presentationTime, C.MICROS_PER_SECOND, long presentationTimesUs = Util.scaleLargeTimestamp(presentationTime, C.MICROS_PER_SECOND,
timescale); timescale);
byte[] eventObject = parseEventObject(xpp, scratchOutputStream); byte[] eventObject = parseEventObject(xpp, scratchOutputStream);
return new Pair<>(presentationTimesUs, buildEvent(schemeIdUri, value, id, durationMs, return buildEvent(schemeIdUri, value, id, durationMs, eventObject, presentationTimesUs);
eventObject));
} }
/** /**
@ -807,8 +806,8 @@ public class DashManifestParser extends DefaultHandler
} }
protected EventMessage buildEvent(String schemeIdUri, String value, long id, protected EventMessage buildEvent(String schemeIdUri, String value, long id,
long durationMs, byte[] messageData) { long durationMs, byte[] messageData, long presentationTimeUs) {
return new EventMessage(schemeIdUri, value, durationMs, id, messageData); return new EventMessage(schemeIdUri, value, durationMs, id, messageData, presentationTimeUs);
} }
protected List<SegmentTimelineElement> parseSegmentTimeline(XmlPullParser xpp) protected List<SegmentTimelineElement> parseSegmentTimeline(XmlPullParser xpp)