public interface

TrackOutput

 androidx.media3.extractor.TrackOutput

Subclasses:

SampleQueue, PlayerEmsgHandler.PlayerTrackEmsgHandler, DummyTrackOutput, FakeTrackOutput

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

Receives track level data extracted by an Extractor.

Summary

Fields
public static final intSAMPLE_DATA_PART_ENCRYPTION

Sample encryption data.

public static final intSAMPLE_DATA_PART_MAIN

Main media sample data.

public static final intSAMPLE_DATA_PART_SUPPLEMENTAL

Sample supplemental data.

Methods
public voidformat(Format format)

Called when the Format of the track has been extracted from the stream.

public intsampleData(DataReader input, int length, boolean allowEndOfInput)

Equivalent to sampleData(input, length, allowEndOfInput, SAMPLE_DATA_PART_MAIN).

public intsampleData(DataReader input, int length, boolean allowEndOfInput, int sampleDataPart)

Called to write sample data to the output.

public voidsampleData(ParsableByteArray data, int length)

Equivalent to TrackOutput.sampleData(ParsableByteArray, int, int) sampleData(data, length, SAMPLE_DATA_PART_MAIN)}.

public voidsampleData(ParsableByteArray data, int length, int sampleDataPart)

Called to write sample data to the output.

public voidsampleMetadata(long timeUs, int flags, int size, int offset, TrackOutput.CryptoData cryptoData)

Called when metadata associated with a sample has been extracted from the stream.

Fields

public static final int SAMPLE_DATA_PART_MAIN

Main media sample data.

public static final int SAMPLE_DATA_PART_ENCRYPTION

Sample encryption data.

The format for encryption information is:

  • (1 byte) encryption_signal_byte: Most significant bit signals whether the encryption data contains subsample encryption data. The remaining bits contain initialization_vector_size.
  • (initialization_vector_size bytes) Initialization vector.
  • If subsample encryption data is present, as per encryption_signal_byte, the encryption data also contains:
    • (2 bytes) subsample_encryption_data_length.
    • (subsample_encryption_data_length * 6 bytes) Subsample encryption data (repeated subsample_encryption_data_length times:
      • (2 bytes) Size of a clear section in sample.
      • (4 bytes) Size of an encryption section in sample.

public static final int SAMPLE_DATA_PART_SUPPLEMENTAL

Sample supplemental data.

If a sample contains supplemental data, the format of the entire sample data will be:

  • If the sample has the C.BUFFER_FLAG_ENCRYPTED flag set, all encryption information.
  • (4 bytes) sample_data_size: The size of the actual sample data, not including supplemental data or encryption information.
  • (sample_data_size bytes): The media sample data.
  • (remaining bytes) The supplemental data.

Methods

public void format(Format format)

Called when the Format of the track has been extracted from the stream.

Parameters:

format: The extracted Format.

public int sampleData(DataReader input, int length, boolean allowEndOfInput)

Equivalent to sampleData(input, length, allowEndOfInput, SAMPLE_DATA_PART_MAIN).

public void sampleData(ParsableByteArray data, int length)

Equivalent to TrackOutput.sampleData(ParsableByteArray, int, int) sampleData(data, length, SAMPLE_DATA_PART_MAIN)}.

public int sampleData(DataReader input, int length, boolean allowEndOfInput, int sampleDataPart)

Called to write sample data to the output.

Parameters:

input: A DataReader from which to read the sample data.
length: The maximum length to read from the input.
allowEndOfInput: True if encountering the end of the input having read no data is allowed, and should result in C.RESULT_END_OF_INPUT being returned. False if it should be considered an error, causing an java.io.EOFException to be thrown.
sampleDataPart: The part of the sample data to which this call corresponds.

Returns:

The number of bytes appended.

public void sampleData(ParsableByteArray data, int length, int sampleDataPart)

Called to write sample data to the output.

Parameters:

data: A ParsableByteArray from which to read the sample data.
length: The number of bytes to read, starting from data.getPosition().
sampleDataPart: The part of the sample data to which this call corresponds.

public void sampleMetadata(long timeUs, int flags, int size, int offset, TrackOutput.CryptoData cryptoData)

Called when metadata associated with a sample has been extracted from the stream.

The corresponding sample data will have already been passed to the output via calls to TrackOutput.sampleData(DataReader, int, boolean) or TrackOutput.sampleData(ParsableByteArray, int).

Parameters:

timeUs: The media timestamp associated with the sample, in microseconds.
flags: Flags associated with the sample. See C.BUFFER_FLAG_*.
size: The size of the sample data, in bytes.
offset: The number of bytes that have been passed to TrackOutput.sampleData(DataReader, int, boolean) or TrackOutput.sampleData(ParsableByteArray, int) since the last byte belonging to the sample whose metadata is being passed.
cryptoData: The encryption data required to decrypt the sample. May be null.

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;

import static java.lang.annotation.ElementType.TYPE_USE;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.DataReader;
import androidx.media3.common.Format;
import androidx.media3.common.util.ParsableByteArray;
import androidx.media3.common.util.UnstableApi;
import java.io.EOFException;
import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;

/** Receives track level data extracted by an {@link Extractor}. */
@UnstableApi
public interface TrackOutput {

  /** Holds data required to decrypt a sample. */
  final class CryptoData {

    /** The encryption mode used for the sample. */
    public final @C.CryptoMode int cryptoMode;

    /** The encryption key associated with the sample. Its contents must not be modified. */
    public final byte[] encryptionKey;

    /**
     * The number of encrypted blocks in the encryption pattern, 0 if pattern encryption does not
     * apply.
     */
    public final int encryptedBlocks;

    /**
     * The number of clear blocks in the encryption pattern, 0 if pattern encryption does not apply.
     */
    public final int clearBlocks;

    /**
     * @param cryptoMode See {@link #cryptoMode}.
     * @param encryptionKey See {@link #encryptionKey}.
     * @param encryptedBlocks See {@link #encryptedBlocks}.
     * @param clearBlocks See {@link #clearBlocks}.
     */
    public CryptoData(
        @C.CryptoMode int cryptoMode, byte[] encryptionKey, int encryptedBlocks, int clearBlocks) {
      this.cryptoMode = cryptoMode;
      this.encryptionKey = encryptionKey;
      this.encryptedBlocks = encryptedBlocks;
      this.clearBlocks = clearBlocks;
    }

    @Override
    public boolean equals(@Nullable Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      CryptoData other = (CryptoData) obj;
      return cryptoMode == other.cryptoMode
          && encryptedBlocks == other.encryptedBlocks
          && clearBlocks == other.clearBlocks
          && Arrays.equals(encryptionKey, other.encryptionKey);
    }

    @Override
    public int hashCode() {
      int result = cryptoMode;
      result = 31 * result + Arrays.hashCode(encryptionKey);
      result = 31 * result + encryptedBlocks;
      result = 31 * result + clearBlocks;
      return result;
    }
  }

  /** Defines the part of the sample data to which a call to {@link #sampleData} corresponds. */
  @Documented
  @Retention(RetentionPolicy.SOURCE)
  @Target(TYPE_USE)
  @IntDef({SAMPLE_DATA_PART_MAIN, SAMPLE_DATA_PART_ENCRYPTION, SAMPLE_DATA_PART_SUPPLEMENTAL})
  @interface SampleDataPart {}

  /** Main media sample data. */
  int SAMPLE_DATA_PART_MAIN = 0;
  /**
   * Sample encryption data.
   *
   * <p>The format for encryption information is:
   *
   * <ul>
   *   <li>(1 byte) {@code encryption_signal_byte}: Most significant bit signals whether the
   *       encryption data contains subsample encryption data. The remaining bits contain {@code
   *       initialization_vector_size}.
   *   <li>({@code initialization_vector_size} bytes) Initialization vector.
   *   <li>If subsample encryption data is present, as per {@code encryption_signal_byte}, the
   *       encryption data also contains:
   *       <ul>
   *         <li>(2 bytes) {@code subsample_encryption_data_length}.
   *         <li>({@code subsample_encryption_data_length * 6} bytes) Subsample encryption data
   *             (repeated {@code subsample_encryption_data_length} times:
   *             <ul>
   *               <li>(2 bytes) Size of a clear section in sample.
   *               <li>(4 bytes) Size of an encryption section in sample.
   *             </ul>
   *       </ul>
   * </ul>
   */
  int SAMPLE_DATA_PART_ENCRYPTION = 1;
  /**
   * Sample supplemental data.
   *
   * <p>If a sample contains supplemental data, the format of the entire sample data will be:
   *
   * <ul>
   *   <li>If the sample has the {@link C#BUFFER_FLAG_ENCRYPTED} flag set, all encryption
   *       information.
   *   <li>(4 bytes) {@code sample_data_size}: The size of the actual sample data, not including
   *       supplemental data or encryption information.
   *   <li>({@code sample_data_size} bytes): The media sample data.
   *   <li>(remaining bytes) The supplemental data.
   * </ul>
   */
  int SAMPLE_DATA_PART_SUPPLEMENTAL = 2;

  /**
   * Called when the {@link Format} of the track has been extracted from the stream.
   *
   * @param format The extracted {@link Format}.
   */
  void format(Format format);

  /**
   * Equivalent to {@link #sampleData(DataReader, int, boolean, int) sampleData(input, length,
   * allowEndOfInput, SAMPLE_DATA_PART_MAIN)}.
   */
  default int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException {
    return sampleData(input, length, allowEndOfInput, SAMPLE_DATA_PART_MAIN);
  }

  /**
   * Equivalent to {@link #sampleData(ParsableByteArray, int, int)} sampleData(data, length,
   * SAMPLE_DATA_PART_MAIN)}.
   */
  default void sampleData(ParsableByteArray data, int length) {
    sampleData(data, length, SAMPLE_DATA_PART_MAIN);
  }

  /**
   * Called to write sample data to the output.
   *
   * @param input A {@link DataReader} from which to read the sample data.
   * @param length The maximum length to read from the input.
   * @param allowEndOfInput True if encountering the end of the input having read no data is
   *     allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
   *     should be considered an error, causing an {@link EOFException} to be thrown.
   * @param sampleDataPart The part of the sample data to which this call corresponds.
   * @return The number of bytes appended.
   * @throws IOException If an error occurred reading from the input.
   */
  int sampleData(
      DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart)
      throws IOException;

  /**
   * Called to write sample data to the output.
   *
   * @param data A {@link ParsableByteArray} from which to read the sample data.
   * @param length The number of bytes to read, starting from {@code data.getPosition()}.
   * @param sampleDataPart The part of the sample data to which this call corresponds.
   */
  void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart);

  /**
   * Called when metadata associated with a sample has been extracted from the stream.
   *
   * <p>The corresponding sample data will have already been passed to the output via calls to
   * {@link #sampleData(DataReader, int, boolean)} or {@link #sampleData(ParsableByteArray, int)}.
   *
   * @param timeUs The media timestamp associated with the sample, in microseconds.
   * @param flags Flags associated with the sample. See {@code C.BUFFER_FLAG_*}.
   * @param size The size of the sample data, in bytes.
   * @param offset The number of bytes that have been passed to {@link #sampleData(DataReader, int,
   *     boolean)} or {@link #sampleData(ParsableByteArray, int)} since the last byte belonging to
   *     the sample whose metadata is being passed.
   * @param cryptoData The encryption data required to decrypt the sample. May be null.
   */
  void sampleMetadata(
      long timeUs, @C.BufferFlags int flags, int size, int offset, @Nullable CryptoData cryptoData);
}