public final class

SpliceInsertCommand

extends SpliceCommand

 java.lang.Object

androidx.media3.extractor.metadata.scte35.SpliceCommand

↳androidx.media3.extractor.metadata.scte35.SpliceInsertCommand

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-extractor', version: '1.0.0-alpha03'

  • groupId: androidx.media3
  • artifactId: media3-extractor
  • version: 1.0.0-alpha03

Artifact androidx.media3:media3-extractor:1.0.0-alpha03 it located at Google repository (https://maven.google.com/)

Overview

Represents a splice insert command defined in SCTE35, Section 9.3.3.

Summary

Fields
public final booleanautoReturn

If SpliceInsertCommand.breakDurationUs is not C.TIME_UNSET, defines whether SpliceInsertCommand.breakDurationUs should be used to know when to return to the network feed.

public final intavailNum

Holds the value of avail_num as defined in SCTE35, Section 9.3.3.

public final intavailsExpected

Holds the value of avails_expected as defined in SCTE35, Section 9.3.3.

public final longbreakDurationUs

The duration of the splice in microseconds, or C.TIME_UNSET if no duration is present.

public final java.util.List<SpliceInsertCommand.ComponentSplice>componentSpliceList

If SpliceInsertCommand.programSpliceFlag is false, a non-empty list containing the SpliceInsertCommand.ComponentSplices.

public static final <any>CREATOR

public final booleanoutOfNetworkIndicator

If true, the splice event is an opportunity to exit from the network feed.

public final booleanprogramSpliceFlag

Whether the splice mode is program splice mode, whereby all PIDs/components are to be spliced.

public final longprogramSplicePlaybackPositionUs

Equivalent to SpliceInsertCommand.programSplicePts but in the playback timebase.

public final longprogramSplicePts

If SpliceInsertCommand.programSpliceFlag is true, the PTS at which the program splice should occur.

public final booleanspliceEventCancelIndicator

True if the event with id SpliceInsertCommand.spliceEventId has been canceled.

public final longspliceEventId

The splice event id.

public final booleanspliceImmediateFlag

Whether splicing should be done at the nearest opportunity.

public final intuniqueProgramId

The unique program id as defined in SCTE35, Section 9.3.3.

Methods
public voidwriteToParcel(Parcel dest, int flags)

from SpliceCommanddescribeContents, toString
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Fields

public final long spliceEventId

The splice event id.

public final boolean spliceEventCancelIndicator

True if the event with id SpliceInsertCommand.spliceEventId has been canceled.

public final boolean outOfNetworkIndicator

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 programSpliceFlag

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 spliceImmediateFlag

Whether splicing should be done at the nearest opportunity. If false, splicing should be done at the moment indicated by SpliceInsertCommand.programSplicePlaybackPositionUs or SpliceInsertCommand.ComponentSplice.componentSplicePlaybackPositionUs, depending on SpliceInsertCommand.programSpliceFlag.

public final long programSplicePts

If SpliceInsertCommand.programSpliceFlag is true, the PTS at which the program splice should occur. C.TIME_UNSET otherwise.

public final long programSplicePlaybackPositionUs

Equivalent to SpliceInsertCommand.programSplicePts but in the playback timebase.

public final java.util.List<SpliceInsertCommand.ComponentSplice> componentSpliceList

If SpliceInsertCommand.programSpliceFlag is false, a non-empty list containing the SpliceInsertCommand.ComponentSplices. Otherwise, an empty list.

public final boolean autoReturn

If SpliceInsertCommand.breakDurationUs is not C.TIME_UNSET, defines whether SpliceInsertCommand.breakDurationUs should be used to know when to return to the network feed. If SpliceInsertCommand.breakDurationUs is C.TIME_UNSET, the value is undefined.

public final long breakDurationUs

The duration of the splice in microseconds, or C.TIME_UNSET if no duration is present.

public final int uniqueProgramId

The unique program id as defined in SCTE35, Section 9.3.3.

public final int availNum

Holds the value of avail_num as defined in SCTE35, Section 9.3.3.

public final int availsExpected

Holds the value of avails_expected as defined in SCTE35, Section 9.3.3.

public static final <any> CREATOR

Methods

public void writeToParcel(Parcel dest, int flags)

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.extractor.metadata.scte35;

import android.os.Parcel;
import android.os.Parcelable;
import androidx.media3.common.C;
import androidx.media3.common.util.ParsableByteArray;
import androidx.media3.common.util.TimestampAdjuster;
import androidx.media3.common.util.UnstableApi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Represents a splice insert command defined in SCTE35, Section 9.3.3. */
@UnstableApi
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;
  /**
   * 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 breakDurationUs,
      int uniqueProgramId,
      int availNum,
      int availsExpected) {
    this.spliceEventId = spliceEventId;
    this.spliceEventCancelIndicator = spliceEventCancelIndicator;
    this.outOfNetworkIndicator = outOfNetworkIndicator;
    this.programSpliceFlag = programSpliceFlag;
    this.spliceImmediateFlag = spliceImmediateFlag;
    this.programSplicePts = programSplicePts;
    this.programSplicePlaybackPositionUs = programSplicePlaybackPositionUs;
    this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
    this.autoReturn = autoReturn;
    this.breakDurationUs = breakDurationUs;
    this.uniqueProgramId = uniqueProgramId;
    this.availNum = availNum;
    this.availsExpected = availsExpected;
  }

  private SpliceInsertCommand(Parcel in) {
    spliceEventId = in.readLong();
    spliceEventCancelIndicator = in.readByte() == 1;
    outOfNetworkIndicator = in.readByte() == 1;
    programSpliceFlag = in.readByte() == 1;
    spliceImmediateFlag = in.readByte() == 1;
    programSplicePts = in.readLong();
    programSplicePlaybackPositionUs = in.readLong();
    int componentSpliceListSize = in.readInt();
    List<ComponentSplice> componentSpliceList = new ArrayList<>(componentSpliceListSize);
    for (int i = 0; i < componentSpliceListSize; i++) {
      componentSpliceList.add(ComponentSplice.createFromParcel(in));
    }
    this.componentSpliceList = Collections.unmodifiableList(componentSpliceList);
    autoReturn = in.readByte() == 1;
    breakDurationUs = in.readLong();
    uniqueProgramId = in.readInt();
    availNum = in.readInt();
    availsExpected = in.readInt();
  }

  /* package */ static SpliceInsertCommand parseFromSection(
      ParsableByteArray sectionData, long ptsAdjustment, TimestampAdjuster timestampAdjuster) {
    long spliceEventId = sectionData.readUnsignedInt();
    // splice_event_cancel_indicator(1), reserved(7).
    boolean spliceEventCancelIndicator = (sectionData.readUnsignedByte() & 0x80) != 0;
    boolean outOfNetworkIndicator = false;
    boolean programSpliceFlag = false;
    boolean spliceImmediateFlag = false;
    long programSplicePts = C.TIME_UNSET;
    List<ComponentSplice> componentSplices = Collections.emptyList();
    int uniqueProgramId = 0;
    int availNum = 0;
    int availsExpected = 0;
    boolean autoReturn = false;
    long breakDurationUs = C.TIME_UNSET;
    if (!spliceEventCancelIndicator) {
      int headerByte = sectionData.readUnsignedByte();
      outOfNetworkIndicator = (headerByte & 0x80) != 0;
      programSpliceFlag = (headerByte & 0x40) != 0;
      boolean durationFlag = (headerByte & 0x20) != 0;
      spliceImmediateFlag = (headerByte & 0x10) != 0;
      if (programSpliceFlag && !spliceImmediateFlag) {
        programSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
      }
      if (!programSpliceFlag) {
        int componentCount = sectionData.readUnsignedByte();
        componentSplices = new ArrayList<>(componentCount);
        for (int i = 0; i < componentCount; i++) {
          int componentTag = sectionData.readUnsignedByte();
          long componentSplicePts = C.TIME_UNSET;
          if (!spliceImmediateFlag) {
            componentSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
          }
          componentSplices.add(
              new ComponentSplice(
                  componentTag,
                  componentSplicePts,
                  timestampAdjuster.adjustTsTimestamp(componentSplicePts)));
        }
      }
      if (durationFlag) {
        long firstByte = sectionData.readUnsignedByte();
        autoReturn = (firstByte & 0x80) != 0;
        long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
        breakDurationUs = breakDuration90khz * 1000 / 90;
      }
      uniqueProgramId = sectionData.readUnsignedShort();
      availNum = sectionData.readUnsignedByte();
      availsExpected = sectionData.readUnsignedByte();
    }
    return new SpliceInsertCommand(
        spliceEventId,
        spliceEventCancelIndicator,
        outOfNetworkIndicator,
        programSpliceFlag,
        spliceImmediateFlag,
        programSplicePts,
        timestampAdjuster.adjustTsTimestamp(programSplicePts),
        componentSplices,
        autoReturn,
        breakDurationUs,
        uniqueProgramId,
        availNum,
        availsExpected);
  }

  /** Holds splicing information for specific splice insert command components. */
  public static final class ComponentSplice {

    public final int componentTag;
    public final long componentSplicePts;
    public final long componentSplicePlaybackPositionUs;

    private ComponentSplice(
        int componentTag, long componentSplicePts, long componentSplicePlaybackPositionUs) {
      this.componentTag = componentTag;
      this.componentSplicePts = componentSplicePts;
      this.componentSplicePlaybackPositionUs = componentSplicePlaybackPositionUs;
    }

    public void writeToParcel(Parcel dest) {
      dest.writeInt(componentTag);
      dest.writeLong(componentSplicePts);
      dest.writeLong(componentSplicePlaybackPositionUs);
    }

    public static ComponentSplice createFromParcel(Parcel in) {
      return new ComponentSplice(in.readInt(), in.readLong(), in.readLong());
    }
  }

  // Parcelable implementation.

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeLong(spliceEventId);
    dest.writeByte((byte) (spliceEventCancelIndicator ? 1 : 0));
    dest.writeByte((byte) (outOfNetworkIndicator ? 1 : 0));
    dest.writeByte((byte) (programSpliceFlag ? 1 : 0));
    dest.writeByte((byte) (spliceImmediateFlag ? 1 : 0));
    dest.writeLong(programSplicePts);
    dest.writeLong(programSplicePlaybackPositionUs);
    int componentSpliceListSize = componentSpliceList.size();
    dest.writeInt(componentSpliceListSize);
    for (int i = 0; i < componentSpliceListSize; i++) {
      componentSpliceList.get(i).writeToParcel(dest);
    }
    dest.writeByte((byte) (autoReturn ? 1 : 0));
    dest.writeLong(breakDurationUs);
    dest.writeInt(uniqueProgramId);
    dest.writeInt(availNum);
    dest.writeInt(availsExpected);
  }

  public static final Parcelable.Creator<SpliceInsertCommand> CREATOR =
      new Parcelable.Creator<SpliceInsertCommand>() {

        @Override
        public SpliceInsertCommand createFromParcel(Parcel in) {
          return new SpliceInsertCommand(in);
        }

        @Override
        public SpliceInsertCommand[] newArray(int size) {
          return new SpliceInsertCommand[size];
        }
      };
}