mirror of
https://github.com/samsonjs/media.git
synced 2026-04-09 11:55:46 +00:00
Improve documentation for SCTE35-related metadata
Also expose break_durations in microseconds instead of 90kHz. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=168816992
This commit is contained in:
parent
a3a2fb506c
commit
6592a6474e
5 changed files with 127 additions and 19 deletions
|
|
@ -24,8 +24,17 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
|||
*/
|
||||
public final class PrivateCommand extends SpliceCommand {
|
||||
|
||||
/**
|
||||
* The {@code pts_adjustment} as defined in SCTE35, Section 9.2.
|
||||
*/
|
||||
public final long ptsAdjustment;
|
||||
/**
|
||||
* The identifier as defined in SCTE35, Section 9.3.6.
|
||||
*/
|
||||
public final long identifier;
|
||||
/**
|
||||
* The private bytes as defined in SCTE35, Section 9.3.6.
|
||||
*/
|
||||
public final byte[] commandBytes;
|
||||
|
||||
private PrivateCommand(long identifier, byte[] commandBytes, long ptsAdjustment) {
|
||||
|
|
|
|||
|
|
@ -29,24 +29,72 @@ import java.util.List;
|
|||
*/
|
||||
public final class SpliceInsertCommand extends SpliceCommand {
|
||||
|
||||
/**
|
||||
* The splice event id.
|
||||
*/
|
||||
public final long spliceEventId;
|
||||
/**
|
||||
* True if the event with id {@link #spliceEventId} has been canceled.
|
||||
*/
|
||||
public final boolean spliceEventCancelIndicator;
|
||||
/**
|
||||
* If true, the splice event is an opportunity to exit from the network feed. If false, indicates
|
||||
* an opportunity to return to the network feed.
|
||||
*/
|
||||
public final boolean outOfNetworkIndicator;
|
||||
/**
|
||||
* Whether the splice mode is program splice mode, whereby all PIDs/components are to be spliced.
|
||||
* If false, splicing is done per PID/component.
|
||||
*/
|
||||
public final boolean programSpliceFlag;
|
||||
/**
|
||||
* Whether splicing should be done at the nearest opportunity. If false, splicing should be done
|
||||
* at the moment indicated by {@link #programSplicePlaybackPositionUs} or
|
||||
* {@link ComponentSplice#componentSplicePlaybackPositionUs}, depending on
|
||||
* {@link #programSpliceFlag}.
|
||||
*/
|
||||
public final boolean spliceImmediateFlag;
|
||||
/**
|
||||
* If {@link #programSpliceFlag} is true, the PTS at which the program splice should occur.
|
||||
* {@link C#TIME_UNSET} otherwise.
|
||||
*/
|
||||
public final long programSplicePts;
|
||||
/**
|
||||
* Equivalent to {@link #programSplicePts} but in the playback timebase.
|
||||
*/
|
||||
public final long programSplicePlaybackPositionUs;
|
||||
/**
|
||||
* If {@link #programSpliceFlag} is false, a non-empty list containing the
|
||||
* {@link ComponentSplice}s. Otherwise, an empty list.
|
||||
*/
|
||||
public final List<ComponentSplice> componentSpliceList;
|
||||
/**
|
||||
* If {@link #breakDurationUs} is not {@link C#TIME_UNSET}, defines whether
|
||||
* {@link #breakDurationUs} should be used to know when to return to the network feed. If
|
||||
* {@link #breakDurationUs} is {@link C#TIME_UNSET}, the value is undefined.
|
||||
*/
|
||||
public final boolean autoReturn;
|
||||
public final long breakDuration;
|
||||
/**
|
||||
* The duration of the splice in microseconds, or {@link C#TIME_UNSET} if no duration is present.
|
||||
*/
|
||||
public final long breakDurationUs;
|
||||
/**
|
||||
* The unique program id as defined in SCTE35, Section 9.3.3.
|
||||
*/
|
||||
public final int uniqueProgramId;
|
||||
/**
|
||||
* Holds the value of {@code avail_num} as defined in SCTE35, Section 9.3.3.
|
||||
*/
|
||||
public final int availNum;
|
||||
/**
|
||||
* Holds the value of {@code avails_expected} as defined in SCTE35, Section 9.3.3.
|
||||
*/
|
||||
public final int availsExpected;
|
||||
|
||||
private SpliceInsertCommand(long spliceEventId, boolean spliceEventCancelIndicator,
|
||||
boolean outOfNetworkIndicator, boolean programSpliceFlag, boolean spliceImmediateFlag,
|
||||
long programSplicePts, long programSplicePlaybackPositionUs,
|
||||
List<ComponentSplice> componentSpliceList, boolean autoReturn, long breakDuration,
|
||||
List<ComponentSplice> componentSpliceList, boolean autoReturn, long breakDurationUs,
|
||||
int uniqueProgramId, int availNum, int availsExpected) {
|
||||
this.spliceEventId = spliceEventId;
|
||||
this.spliceEventCancelIndicator = spliceEventCancelIndicator;
|
||||
|
|
@ -57,7 +105,7 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
this.programSplicePlaybackPositionUs = programSplicePlaybackPositionUs;
|
||||
this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
|
||||
this.autoReturn = autoReturn;
|
||||
this.breakDuration = breakDuration;
|
||||
this.breakDurationUs = breakDurationUs;
|
||||
this.uniqueProgramId = uniqueProgramId;
|
||||
this.availNum = availNum;
|
||||
this.availsExpected = availsExpected;
|
||||
|
|
@ -78,7 +126,7 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
}
|
||||
this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
|
||||
autoReturn = in.readByte() == 1;
|
||||
breakDuration = in.readLong();
|
||||
breakDurationUs = in.readLong();
|
||||
uniqueProgramId = in.readInt();
|
||||
availNum = in.readInt();
|
||||
availsExpected = in.readInt();
|
||||
|
|
@ -98,7 +146,7 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
int availNum = 0;
|
||||
int availsExpected = 0;
|
||||
boolean autoReturn = false;
|
||||
long duration = C.TIME_UNSET;
|
||||
long breakDurationUs = C.TIME_UNSET;
|
||||
if (!spliceEventCancelIndicator) {
|
||||
int headerByte = sectionData.readUnsignedByte();
|
||||
outOfNetworkIndicator = (headerByte & 0x80) != 0;
|
||||
|
|
@ -124,7 +172,8 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
if (durationFlag) {
|
||||
long firstByte = sectionData.readUnsignedByte();
|
||||
autoReturn = (firstByte & 0x80) != 0;
|
||||
duration = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
|
||||
long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
|
||||
breakDurationUs = breakDuration90khz * 1000 / 90;
|
||||
}
|
||||
uniqueProgramId = sectionData.readUnsignedShort();
|
||||
availNum = sectionData.readUnsignedByte();
|
||||
|
|
@ -133,7 +182,7 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
return new SpliceInsertCommand(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
|
||||
programSpliceFlag, spliceImmediateFlag, programSplicePts,
|
||||
timestampAdjuster.adjustTsTimestamp(programSplicePts), componentSplices, autoReturn,
|
||||
duration, uniqueProgramId, availNum, availsExpected);
|
||||
breakDurationUs, uniqueProgramId, availNum, availsExpected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -181,7 +230,7 @@ public final class SpliceInsertCommand extends SpliceCommand {
|
|||
componentSpliceList.get(i).writeToParcel(dest);
|
||||
}
|
||||
dest.writeByte((byte) (autoReturn ? 1 : 0));
|
||||
dest.writeLong(breakDuration);
|
||||
dest.writeLong(breakDurationUs);
|
||||
dest.writeInt(uniqueProgramId);
|
||||
dest.writeInt(availNum);
|
||||
dest.writeInt(availsExpected);
|
||||
|
|
|
|||
|
|
@ -33,22 +33,62 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
*/
|
||||
public static final class Event {
|
||||
|
||||
/**
|
||||
* The splice event id.
|
||||
*/
|
||||
public final long spliceEventId;
|
||||
/**
|
||||
* True if the event with id {@link #spliceEventId} has been canceled.
|
||||
*/
|
||||
public final boolean spliceEventCancelIndicator;
|
||||
/**
|
||||
* If true, the splice event is an opportunity to exit from the network feed. If false,
|
||||
* indicates an opportunity to return to the network feed.
|
||||
*/
|
||||
public final boolean outOfNetworkIndicator;
|
||||
/**
|
||||
* Whether the splice mode is program splice mode, whereby all PIDs/components are to be
|
||||
* spliced. If false, splicing is done per PID/component.
|
||||
*/
|
||||
public final boolean programSpliceFlag;
|
||||
/**
|
||||
* Represents the time of the signaled splice event as the number of seconds since 00 hours UTC,
|
||||
* January 6th, 1980, with the count of intervening leap seconds included.
|
||||
*/
|
||||
public final long utcSpliceTime;
|
||||
/**
|
||||
* If {@link #programSpliceFlag} is false, a non-empty list containing the
|
||||
* {@link ComponentSplice}s. Otherwise, an empty list.
|
||||
*/
|
||||
public final List<ComponentSplice> componentSpliceList;
|
||||
/**
|
||||
* If {@link #breakDurationUs} is not {@link C#TIME_UNSET}, defines whether
|
||||
* {@link #breakDurationUs} should be used to know when to return to the network feed. If
|
||||
* {@link #breakDurationUs} is {@link C#TIME_UNSET}, the value is undefined.
|
||||
*/
|
||||
public final boolean autoReturn;
|
||||
public final long breakDuration;
|
||||
/**
|
||||
* The duration of the splice in microseconds, or {@link C#TIME_UNSET} if no duration is
|
||||
* present.
|
||||
*/
|
||||
public final long breakDurationUs;
|
||||
/**
|
||||
* The unique program id as defined in SCTE35, Section 9.3.2.
|
||||
*/
|
||||
public final int uniqueProgramId;
|
||||
/**
|
||||
* Holds the value of {@code avail_num} as defined in SCTE35, Section 9.3.2.
|
||||
*/
|
||||
public final int availNum;
|
||||
/**
|
||||
* Holds the value of {@code avails_expected} as defined in SCTE35, Section 9.3.2.
|
||||
*/
|
||||
public final int availsExpected;
|
||||
|
||||
private Event(long spliceEventId, boolean spliceEventCancelIndicator,
|
||||
boolean outOfNetworkIndicator, boolean programSpliceFlag,
|
||||
List<ComponentSplice> componentSpliceList, long utcSpliceTime, boolean autoReturn,
|
||||
long breakDuration, int uniqueProgramId, int availNum, int availsExpected) {
|
||||
long breakDurationUs, int uniqueProgramId, int availNum, int availsExpected) {
|
||||
this.spliceEventId = spliceEventId;
|
||||
this.spliceEventCancelIndicator = spliceEventCancelIndicator;
|
||||
this.outOfNetworkIndicator = outOfNetworkIndicator;
|
||||
|
|
@ -56,7 +96,7 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
|
||||
this.utcSpliceTime = utcSpliceTime;
|
||||
this.autoReturn = autoReturn;
|
||||
this.breakDuration = breakDuration;
|
||||
this.breakDurationUs = breakDurationUs;
|
||||
this.uniqueProgramId = uniqueProgramId;
|
||||
this.availNum = availNum;
|
||||
this.availsExpected = availsExpected;
|
||||
|
|
@ -75,7 +115,7 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
|
||||
this.utcSpliceTime = in.readLong();
|
||||
this.autoReturn = in.readByte() == 1;
|
||||
this.breakDuration = in.readLong();
|
||||
this.breakDurationUs = in.readLong();
|
||||
this.uniqueProgramId = in.readInt();
|
||||
this.availNum = in.readInt();
|
||||
this.availsExpected = in.readInt();
|
||||
|
|
@ -93,7 +133,7 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
int availNum = 0;
|
||||
int availsExpected = 0;
|
||||
boolean autoReturn = false;
|
||||
long duration = C.TIME_UNSET;
|
||||
long breakDurationUs = C.TIME_UNSET;
|
||||
if (!spliceEventCancelIndicator) {
|
||||
int headerByte = sectionData.readUnsignedByte();
|
||||
outOfNetworkIndicator = (headerByte & 0x80) != 0;
|
||||
|
|
@ -114,15 +154,16 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
if (durationFlag) {
|
||||
long firstByte = sectionData.readUnsignedByte();
|
||||
autoReturn = (firstByte & 0x80) != 0;
|
||||
duration = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
|
||||
long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
|
||||
breakDurationUs = breakDuration90khz * 1000 / 90;
|
||||
}
|
||||
uniqueProgramId = sectionData.readUnsignedShort();
|
||||
availNum = sectionData.readUnsignedByte();
|
||||
availsExpected = sectionData.readUnsignedByte();
|
||||
}
|
||||
return new Event(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
|
||||
programSpliceFlag, componentSplices, utcSpliceTime, autoReturn, duration, uniqueProgramId,
|
||||
availNum, availsExpected);
|
||||
programSpliceFlag, componentSplices, utcSpliceTime, autoReturn, breakDurationUs,
|
||||
uniqueProgramId, availNum, availsExpected);
|
||||
}
|
||||
|
||||
private void writeToParcel(Parcel dest) {
|
||||
|
|
@ -137,7 +178,7 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
}
|
||||
dest.writeLong(utcSpliceTime);
|
||||
dest.writeByte((byte) (autoReturn ? 1 : 0));
|
||||
dest.writeLong(breakDuration);
|
||||
dest.writeLong(breakDurationUs);
|
||||
dest.writeInt(uniqueProgramId);
|
||||
dest.writeInt(availNum);
|
||||
dest.writeInt(availsExpected);
|
||||
|
|
@ -173,6 +214,9 @@ public final class SpliceScheduleCommand extends SpliceCommand {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of scheduled events.
|
||||
*/
|
||||
public final List<Event> events;
|
||||
|
||||
private SpliceScheduleCommand(List<Event> events) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,13 @@ import com.google.android.exoplayer2.util.TimestampAdjuster;
|
|||
*/
|
||||
public final class TimeSignalCommand extends SpliceCommand {
|
||||
|
||||
/**
|
||||
* A PTS value, as defined in SCTE35, Section 9.3.4.
|
||||
*/
|
||||
public final long ptsTime;
|
||||
/**
|
||||
* Equivalent to {@link #ptsTime} but in the playback timebase.
|
||||
*/
|
||||
public final long playbackPositionUs;
|
||||
|
||||
private TimeSignalCommand(long ptsTime, long playbackPositionUs) {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ public final class SpliceInfoDecoderTest {
|
|||
assertThat(command.programSpliceFlag).isTrue();
|
||||
assertThat(command.spliceImmediateFlag).isFalse();
|
||||
assertThat(command.programSplicePlaybackPositionUs).isEqualTo(3000000);
|
||||
assertThat(command.breakDuration).isEqualTo(TIME_UNSET);
|
||||
assertThat(command.breakDurationUs).isEqualTo(TIME_UNSET);
|
||||
assertThat(command.uniqueProgramId).isEqualTo(16);
|
||||
assertThat(command.availNum).isEqualTo(1);
|
||||
assertThat(command.availsExpected).isEqualTo(2);
|
||||
|
|
@ -155,7 +155,7 @@ public final class SpliceInfoDecoderTest {
|
|||
assertThat(command.programSpliceFlag).isFalse();
|
||||
assertThat(command.spliceImmediateFlag).isFalse();
|
||||
assertThat(command.programSplicePlaybackPositionUs).isEqualTo(TIME_UNSET);
|
||||
assertThat(command.breakDuration).isEqualTo(TIME_UNSET);
|
||||
assertThat(command.breakDurationUs).isEqualTo(TIME_UNSET);
|
||||
List<SpliceInsertCommand.ComponentSplice> componentSplices = command.componentSpliceList;
|
||||
assertThat(componentSplices).hasSize(2);
|
||||
assertThat(componentSplices.get(0).componentTag).isEqualTo(16);
|
||||
|
|
|
|||
Loading…
Reference in a new issue