/*
 * Copyright (C) 2019 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 android.media;

import android.annotation.CheckResult;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.media.MediaCodec.CryptoInfo;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
import com.google.android.exoplayer2.extractor.flac.FlacExtractor;
import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
import com.google.android.exoplayer2.extractor.ts.Ac4Extractor;
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
import com.google.android.exoplayer2.extractor.ts.PsExtractor;
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
import com.google.android.exoplayer2.extractor.wav.WavExtractor;
import com.google.android.exoplayer2.upstream.DataReader;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.ColorInfo;

import java.io.EOFException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Parses media container formats and extracts contained media samples and metadata.
 *
 * <p>This class provides access to a battery of low-level media container parsers. Each instance of
 * this class is associated to a specific media parser implementation which is suitable for
 * extraction from a specific media container format. The media parser implementation assignment
 * depends on the factory method (see {@link #create} and {@link #createByName}) used to create the
 * instance.
 *
 * <p>Users must implement the following to use this class.
 *
 * <ul>
 *   <li>{@link InputReader}: Provides the media container's bytes to parse.
 *   <li>{@link OutputConsumer}: Provides a sink for all extracted data and metadata.
 * </ul>
 *
 * <p>The following code snippet includes a usage example:
 *
 * <pre>
 * MyOutputConsumer myOutputConsumer = new MyOutputConsumer();
 * MyInputReader myInputReader = new MyInputReader("www.example.com");
 * MediaParser mediaParser = MediaParser.create(myOutputConsumer);
 *
 * while (mediaParser.advance(myInputReader)) {}
 *
 * mediaParser.release();
 * mediaParser = null;
 * </pre>
 *
 * <p>The following code snippet provides a rudimentary {@link OutputConsumer} sample implementation
 * which extracts and publishes all video samples:
 *
 * <pre>
 * class VideoOutputConsumer implements MediaParser.OutputConsumer {
 *
 *     private byte[] sampleDataBuffer = new byte[4096];
 *     private byte[] discardedDataBuffer = new byte[4096];
 *     private int videoTrackIndex = -1;
 *     private int bytesWrittenCount = 0;
 *
 *     &#64;Override
 *     public void onSeekMapFound(int i, &#64;NonNull MediaFormat mediaFormat) {
 *       // Do nothing.
 *     }
 *
 *     &#64;Override
 *     public void onTrackDataFound(int i, &#64;NonNull TrackData trackData) {
 *       MediaFormat mediaFormat = trackData.mediaFormat;
 *       if (videoTrackIndex == -1 &amp;&amp;
 *           mediaFormat
 *               .getString(MediaFormat.KEY_MIME, &#47;* defaultValue= *&#47; "")
 *               .startsWith("video/")) {
 *         videoTrackIndex = i;
 *       }
 *     }
 *
 *     &#64;Override
 *     public void onSampleDataFound(int trackIndex, &#64;NonNull InputReader inputReader)
 *         throws IOException {
 *       int numberOfBytesToRead = (int) inputReader.getLength();
 *       if (videoTrackIndex != trackIndex) {
 *         // Discard contents.
 *         inputReader.read(
 *             discardedDataBuffer,
 *             &#47;* offset= *&#47; 0,
 *             Math.min(discardDataBuffer.length, numberOfBytesToRead));
 *       } else {
 *         ensureSpaceInBuffer(numberOfBytesToRead);
 *         int bytesRead = inputReader.read(
 *             sampleDataBuffer, bytesWrittenCount, numberOfBytesToRead);
 *         bytesWrittenCount += bytesRead;
 *       }
 *     }
 *
 *     &#64;Override
 *     public void onSampleCompleted(
 *         int trackIndex,
 *         long timeMicros,
 *         int flags,
 *         int size,
 *         int offset,
 *         &#64;Nullable CryptoInfo cryptoData) {
 *       if (videoTrackIndex != trackIndex) {
 *         return; // It's not the video track. Ignore.
 *       }
 *       byte[] sampleData = new byte[size];
 *       int sampleStartOffset = bytesWrittenCount - size - offset;
 *       System.arraycopy(
 *           sampleDataBuffer,
 *           sampleStartOffset,
 *           sampleData,
 *           &#47;* destPos= *&#47; 0,
 *           size);
 *       // Place trailing bytes at the start of the buffer.
 *       System.arraycopy(
 *           sampleDataBuffer,
 *           bytesWrittenCount - offset,
 *           sampleDataBuffer,
 *           &#47;* destPos= *&#47; 0,
 *           &#47;* size= *&#47; offset);
 *       bytesWrittenCount = bytesWrittenCount - offset;
 *       publishSample(sampleData, timeMicros, flags);
 *     }
 *
 *    private void ensureSpaceInBuffer(int numberOfBytesToRead) {
 *      int requiredLength = bytesWrittenCount + numberOfBytesToRead;
 *      if (requiredLength &gt; sampleDataBuffer.length) {
 *        sampleDataBuffer = Arrays.copyOf(sampleDataBuffer, requiredLength);
 *      }
 *    }
 *
 *   }
 *
 * </pre>
 */
public final class MediaParser {

    /**
     * Maps seek positions to {@link SeekPoint SeekPoints} in the stream.
     *
     * <p>A {@link SeekPoint} is a position in the stream from which a player may successfully start
     * playing media samples.
     */
    public static final class SeekMap {

        /** Returned by {@link #getDurationMicros()} when the duration is unknown. */
        public static final int UNKNOWN_DURATION = Integer.MIN_VALUE;

        private final com.google.android.exoplayer2.extractor.SeekMap mExoPlayerSeekMap;

        private SeekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
            mExoPlayerSeekMap = exoplayerSeekMap;
        }

        /** Returns whether seeking is supported. */
        public boolean isSeekable() {
            return mExoPlayerSeekMap.isSeekable();
        }

        /**
         * Returns the duration of the stream in microseconds or {@link #UNKNOWN_DURATION} if the
         * duration is unknown.
         */
        public long getDurationMicros() {
            return mExoPlayerSeekMap.getDurationUs();
        }

        /**
         * Obtains {@link SeekPoint SeekPoints} for the specified seek time in microseconds.
         *
         * <p>{@code getSeekPoints(timeMicros).first} contains the latest seek point for samples
         * with timestamp equal to or smaller than {@code timeMicros}.
         *
         * <p>{@code getSeekPoints(timeMicros).second} contains the earliest seek point for samples
         * with timestamp equal to or greater than {@code timeMicros}. If a seek point exists for
         * {@code timeMicros}, the returned pair will contain the same {@link SeekPoint} twice.
         *
         * @param timeMicros A seek time in microseconds.
         * @return The corresponding {@link SeekPoint SeekPoints}.
         */
        @NonNull
        public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeMicros) {
            SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeMicros);
            return new Pair<>(toSeekPoint(seekPoints.first), toSeekPoint(seekPoints.second));
        }
    }

    /** Holds information associated with a track. */
    public static final class TrackData {

        /** Holds {@link MediaFormat} information for the track. */
        @NonNull public final MediaFormat mediaFormat;

        /**
         * Holds {@link DrmInitData} necessary to acquire keys associated with the track, or null if
         * the track has no encryption data.
         */
        @Nullable public final DrmInitData drmInitData;

        private TrackData(MediaFormat mediaFormat, DrmInitData drmInitData) {
            this.mediaFormat = mediaFormat;
            this.drmInitData = drmInitData;
        }
    }

    /** Defines a seek point in a media stream. */
    public static final class SeekPoint {

        /** A {@link SeekPoint} whose time and byte offset are both set to 0. */
        @NonNull public static final SeekPoint START = new SeekPoint(0, 0);

        /** The time of the seek point, in microseconds. */
        public final long timeMicros;

        /** The byte offset of the seek point. */
        public final long position;

        /**
         * @param timeMicros The time of the seek point, in microseconds.
         * @param position The byte offset of the seek point.
         */
        private SeekPoint(long timeMicros, long position) {
            this.timeMicros = timeMicros;
            this.position = position;
        }

        @Override
        @NonNull
        public String toString() {
            return "[timeMicros=" + timeMicros + ", position=" + position + "]";
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            SeekPoint other = (SeekPoint) obj;
            return timeMicros == other.timeMicros && position == other.position;
        }

        @Override
        public int hashCode() {
            int result = (int) timeMicros;
            result = 31 * result + (int) position;
            return result;
        }
    }

    /** Provides input data to {@link MediaParser}. */
    public interface InputReader {

        /**
         * Reads up to {@code readLength} bytes of data and stores them into {@code buffer},
         * starting at index {@code offset}.
         *
         * <p>This method blocks until at least one byte is read, the end of input is detected, or
         * an exception is thrown. The read position advances to the first unread byte.
         *
         * @param buffer The buffer into which the read data should be stored.
         * @param offset The start offset into {@code buffer} at which data should be written.
         * @param readLength The maximum number of bytes to read.
         * @return The non-zero number of bytes read, or -1 if no data is available because the end
         *     of the input has been reached.
         * @throws java.io.IOException If an error occurs reading from the source.
         */
        int read(@NonNull byte[] buffer, int offset, int readLength) throws IOException;

        /** Returns the current read position (byte offset) in the stream. */
        long getPosition();

        /** Returns the length of the input in bytes, or -1 if the length is unknown. */
        long getLength();
    }

    /** {@link InputReader} that allows setting the read position. */
    public interface SeekableInputReader extends InputReader {

        /**
         * Sets the read position at the given {@code position}.
         *
         * <p>{@link #advance} will immediately return after calling this method.
         *
         * @param position The position to seek to, in bytes.
         */
        void seekToPosition(long position);
    }

    /** Receives extracted media sample data and metadata from {@link MediaParser}. */
    public interface OutputConsumer {

        /**
         * Called when a {@link SeekMap} has been extracted from the stream.
         *
         * <p>This method is called at least once before any samples are {@link #onSampleCompleted
         * complete}. May be called multiple times after that in order to add {@link SeekPoint
         * SeekPoints}.
         *
         * @param seekMap The extracted {@link SeekMap}.
         */
        void onSeekMapFound(@NonNull SeekMap seekMap);

        /**
         * Called when the number of tracks is found.
         *
         * @param numberOfTracks The number of tracks in the stream.
         */
        void onTrackCountFound(int numberOfTracks);

        /**
         * Called when new {@link TrackData} is found in the stream.
         *
         * @param trackIndex The index of the track for which the {@link TrackData} was extracted.
         * @param trackData The extracted {@link TrackData}.
         */
        void onTrackDataFound(int trackIndex, @NonNull TrackData trackData);

        /**
         * Called when sample data is found in the stream.
         *
         * <p>If the invocation of this method returns before the entire {@code inputReader} {@link
         * InputReader#getLength() length} is consumed, the method will be called again for the
         * implementer to read the remaining data. Implementers should surface any thrown {@link
         * IOException} caused by reading from {@code input}.
         *
         * @param trackIndex The index of the track to which the sample data corresponds.
         * @param inputReader The {@link InputReader} from which to read the data.
         * @throws IOException If an exception occurs while reading from {@code inputReader}.
         */
        void onSampleDataFound(int trackIndex, @NonNull InputReader inputReader) throws IOException;

        /**
         * Called once all the data of a sample has been passed to {@link #onSampleDataFound}.
         *
         * <p>Includes sample metadata, like presentation timestamp and flags.
         *
         * @param trackIndex The index of the track to which the sample corresponds.
         * @param timeMicros The media timestamp associated with the sample, in microseconds.
         * @param flags Flags associated with the sample. See the {@code SAMPLE_FLAG_*} constants.
         * @param size The size of the sample data, in bytes.
         * @param offset The number of bytes that have been consumed by {@code
         *     onSampleDataFound(int, MediaParser.InputReader)} for the specified track, since the
         *     last byte belonging to the sample whose metadata is being passed.
         * @param cryptoInfo Encryption data required to decrypt the sample. May be null for
         *     unencrypted samples. MediaParser may reuse {@link CryptoInfo} instances to avoid
         *     allocations, so implementations of this method must not write to or keep reference to
         *     the fields of this parameter.
         */
        void onSampleCompleted(
                int trackIndex,
                long timeMicros,
                @SampleFlags int flags,
                int size,
                int offset,
                @Nullable CryptoInfo cryptoInfo);
    }

    /**
     * Thrown if all parser implementations provided to {@link #create} failed to sniff the input
     * content.
     */
    public static final class UnrecognizedInputFormatException extends IOException {

        /**
         * Creates a new instance which signals that the parsers with the given names failed to
         * parse the input.
         */
        @NonNull
        @CheckResult
        private static UnrecognizedInputFormatException createForExtractors(
                @NonNull String... extractorNames) {
            StringBuilder builder = new StringBuilder();
            builder.append("None of the available parsers ( ");
            builder.append(extractorNames[0]);
            for (int i = 1; i < extractorNames.length; i++) {
                builder.append(", ");
                builder.append(extractorNames[i]);
            }
            builder.append(") could read the stream.");
            return new UnrecognizedInputFormatException(builder.toString());
        }

        private UnrecognizedInputFormatException(String extractorNames) {
            super(extractorNames);
        }
    }

    /** Thrown when an error occurs while parsing a media stream. */
    public static final class ParsingException extends IOException {

        private ParsingException(ParserException cause) {
            super(cause);
        }
    }

    // Sample flags.

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            flag = true,
            value = {
                SAMPLE_FLAG_KEY_FRAME,
                SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA,
                SAMPLE_FLAG_LAST_SAMPLE,
                SAMPLE_FLAG_ENCRYPTED,
                SAMPLE_FLAG_DECODE_ONLY
            })
    public @interface SampleFlags {}
    /** Indicates that the sample holds a synchronization sample. */
    public static final int SAMPLE_FLAG_KEY_FRAME = MediaCodec.BUFFER_FLAG_KEY_FRAME;
    /** Indicates that the sample has supplemental data. */
    public static final int SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA = 1 << 28;
    /** Indicates that the sample is known to contain the last media sample of the stream. */
    public static final int SAMPLE_FLAG_LAST_SAMPLE = 1 << 29;
    /** Indicates that the sample is (at least partially) encrypted. */
    public static final int SAMPLE_FLAG_ENCRYPTED = 1 << 30;
    /** Indicates that the sample should be decoded but not rendered. */
    public static final int SAMPLE_FLAG_DECODE_ONLY = 1 << 31;

    // Parser implementation names.

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @StringDef(
            prefix = {"PARSER_NAME_"},
            value = {
                PARSER_NAME_UNKNOWN,
                PARSER_NAME_MATROSKA,
                PARSER_NAME_FMP4,
                PARSER_NAME_MP4,
                PARSER_NAME_MP3,
                PARSER_NAME_ADTS,
                PARSER_NAME_AC3,
                PARSER_NAME_TS,
                PARSER_NAME_FLV,
                PARSER_NAME_OGG,
                PARSER_NAME_PS,
                PARSER_NAME_WAV,
                PARSER_NAME_AMR,
                PARSER_NAME_AC4,
                PARSER_NAME_FLAC
            })
    public @interface ParserName {}

    /** Parser name returned by {@link #getParserName()} when no parser has been selected yet. */
    public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN";
    /**
     * Parser for the Matroska container format, as defined in the <a
     * href="https://matroska.org/technical/specs/">spec</a>.
     */
    public static final String PARSER_NAME_MATROSKA = "android.media.mediaparser.MatroskaParser";
    /**
     * Parser for fragmented files using the MP4 container format, as defined in ISO/IEC 14496-12.
     */
    public static final String PARSER_NAME_FMP4 = "android.media.mediaparser.FragmentedMp4Parser";
    /**
     * Parser for non-fragmented files using the MP4 container format, as defined in ISO/IEC
     * 14496-12.
     */
    public static final String PARSER_NAME_MP4 = "android.media.mediaparser.Mp4Parser";
    /** Parser for the MP3 container format, as defined in ISO/IEC 11172-3. */
    public static final String PARSER_NAME_MP3 = "android.media.mediaparser.Mp3Parser";
    /** Parser for the ADTS container format, as defined in ISO/IEC 13818-7. */
    public static final String PARSER_NAME_ADTS = "android.media.mediaparser.AdtsParser";
    /**
     * Parser for the AC-3 container format, as defined in Digital Audio Compression Standard
     * (AC-3).
     */
    public static final String PARSER_NAME_AC3 = "android.media.mediaparser.Ac3Parser";
    /** Parser for the TS container format, as defined in ISO/IEC 13818-1. */
    public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser";
    /**
     * Parser for the FLV container format, as defined in Adobe Flash Video File Format
     * Specification.
     */
    public static final String PARSER_NAME_FLV = "android.media.mediaparser.FlvParser";
    /** Parser for the OGG container format, as defined in RFC 3533. */
    public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser";
    /** Parser for the PS container format, as defined in ISO/IEC 11172-1. */
    public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser";
    /**
     * Parser for the WAV container format, as defined in Multimedia Programming Interface and Data
     * Specifications.
     */
    public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser";
    /** Parser for the AMR container format, as defined in RFC 4867. */
    public static final String PARSER_NAME_AMR = "android.media.mediaparser.AmrParser";
    /**
     * Parser for the AC-4 container format, as defined by Dolby AC-4: Audio delivery for
     * Next-Generation Entertainment Services.
     */
    public static final String PARSER_NAME_AC4 = "android.media.mediaparser.Ac4Parser";
    /**
     * Parser for the FLAC container format, as defined in the <a
     * href="https://xiph.org/flac/">spec</a>.
     */
    public static final String PARSER_NAME_FLAC = "android.media.mediaparser.FlacParser";

    // MediaParser parameters.

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @StringDef(
            prefix = {"PARAMETER_"},
            value = {
                PARAMETER_ADTS_ENABLE_CBR_SEEKING,
                PARAMETER_AMR_ENABLE_CBR_SEEKING,
                PARAMETER_FLAC_DISABLE_ID3,
                PARAMETER_MP4_IGNORE_EDIT_LISTS,
                PARAMETER_MP4_IGNORE_TFDT_BOX,
                PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES,
                PARAMETER_MATROSKA_DISABLE_CUES_SEEKING,
                PARAMETER_MP3_DISABLE_ID3,
                PARAMETER_MP3_ENABLE_CBR_SEEKING,
                PARAMETER_MP3_ENABLE_INDEX_SEEKING,
                PARAMETER_TS_MODE,
                PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES,
                PARAMETER_TS_IGNORE_AAC_STREAM,
                PARAMETER_TS_IGNORE_AVC_STREAM,
                PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM,
                PARAMETER_TS_DETECT_ACCESS_UNITS,
                PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS
            })
    public @interface ParameterName {}

    /**
     * Sets whether constant bitrate seeking should be enabled for ADTS parsing. {@code boolean}
     * expected. Default value is {@code false}.
     */
    public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING =
            "android.media.mediaparser.adts.enableCbrSeeking";
    /**
     * Sets whether constant bitrate seeking should be enabled for AMR. {@code boolean} expected.
     * Default value is {@code false}.
     */
    public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING =
            "android.media.mediaparser.amr.enableCbrSeeking";
    /**
     * Sets whether the ID3 track should be disabled for FLAC. {@code boolean} expected. Default
     * value is {@code false}.
     */
    public static final String PARAMETER_FLAC_DISABLE_ID3 =
            "android.media.mediaparser.flac.disableId3";
    /**
     * Sets whether MP4 parsing should ignore edit lists. {@code boolean} expected. Default value is
     * {@code false}.
     */
    public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS =
            "android.media.mediaparser.mp4.ignoreEditLists";
    /**
     * Sets whether MP4 parsing should ignore the tfdt box. {@code boolean} expected. Default value
     * is {@code false}.
     */
    public static final String PARAMETER_MP4_IGNORE_TFDT_BOX =
            "android.media.mediaparser.mp4.ignoreTfdtBox";
    /**
     * Sets whether MP4 parsing should treat all video frames as key frames. {@code boolean}
     * expected. Default value is {@code false}.
     */
    public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
            "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
    /**
     * Sets whether Matroska parsing should avoid seeking to the cues element. {@code boolean}
     * expected. Default value is {@code false}.
     *
     * <p>If this flag is enabled and the cues element occurs after the first cluster, then the
     * media is treated as unseekable.
     */
    public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING =
            "android.media.mediaparser.matroska.disableCuesSeeking";
    /**
     * Sets whether the ID3 track should be disabled for MP3. {@code boolean} expected. Default
     * value is {@code false}.
     */
    public static final String PARAMETER_MP3_DISABLE_ID3 =
            "android.media.mediaparser.mp3.disableId3";
    /**
     * Sets whether constant bitrate seeking should be enabled for MP3. {@code boolean} expected.
     * Default value is {@code false}.
     */
    public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING =
            "android.media.mediaparser.mp3.enableCbrSeeking";
    /**
     * Sets whether MP3 parsing should generate a time-to-byte mapping. {@code boolean} expected.
     * Default value is {@code false}.
     *
     * <p>Enabling this flag may require to scan a significant portion of the file to compute a seek
     * point. Therefore, it should only be used if:
     *
     * <ul>
     *   <li>the file is small, or
     *   <li>the bitrate is variable (or the type of bitrate is unknown) and the seeking metadata
     *       provided in the file is not precise enough (or is not present).
     * </ul>
     */
    public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING =
            "android.media.mediaparser.mp3.enableIndexSeeking";
    /**
     * Sets the operation mode for TS parsing. {@code String} expected. Valid values are {@code
     * "single_pmt"}, {@code "multi_pmt"}, and {@code "hls"}. Default value is {@code "single_pmt"}.
     *
     * <p>The operation modes alter the way TS behaves so that it can handle certain kinds of
     * commonly-occurring malformed media.
     *
     * <ul>
     *   <li>{@code "single_pmt"}: Only the first found PMT is parsed. Others are ignored, even if
     *       more PMTs are declared in the PAT.
     *   <li>{@code "multi_pmt"}: Behave as described in ISO/IEC 13818-1.
     *   <li>{@code "hls"}: Enable {@code "single_pmt"} mode, and ignore continuity counters.
     * </ul>
     */
    public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
    /**
     * Sets whether TS should treat samples consisting of non-IDR I slices as synchronization
     * samples (key-frames). {@code boolean} expected. Default value is {@code false}.
     */
    public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES =
            "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
    /**
     * Sets whether TS parsing should ignore AAC elementary streams. {@code boolean} expected.
     * Default value is {@code false}.
     */
    public static final String PARAMETER_TS_IGNORE_AAC_STREAM =
            "android.media.mediaparser.ts.ignoreAacStream";
    /**
     * Sets whether TS parsing should ignore AVC elementary streams. {@code boolean} expected.
     * Default value is {@code false}.
     */
    public static final String PARAMETER_TS_IGNORE_AVC_STREAM =
            "android.media.mediaparser.ts.ignoreAvcStream";
    /**
     * Sets whether TS parsing should ignore splice information streams. {@code boolean} expected.
     * Default value is {@code false}.
     */
    public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM =
            "android.media.mediaparser.ts.ignoreSpliceInfoStream";
    /**
     * Sets whether TS parsing should split AVC stream into access units based on slice headers.
     * {@code boolean} expected. Default value is {@code false}.
     *
     * <p>This flag should be left disabled if the stream contains access units delimiters in order
     * to avoid unnecessary computational costs.
     */
    public static final String PARAMETER_TS_DETECT_ACCESS_UNITS =
            "android.media.mediaparser.ts.ignoreDetectAccessUnits";
    /**
     * Sets whether TS parsing should handle HDMV DTS audio streams. {@code boolean} expected.
     * Default value is {@code false}.
     *
     * <p>Enabling this flag will disable the detection of SCTE subtitles.
     */
    public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS =
            "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";

    // Private constants.

    private static final String TAG = "MediaParser";
    private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME;
    private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME;
    private static final String TS_MODE_SINGLE_PMT = "single_pmt";
    private static final String TS_MODE_MULTI_PMT = "multi_pmt";
    private static final String TS_MODE_HLS = "hls";

    // Instance creation methods.

    /**
     * Creates an instance backed by the parser with the given {@code name}. The returned instance
     * will attempt parsing without sniffing the content.
     *
     * @param name The name of the parser that will be associated with the created instance.
     * @param outputConsumer The {@link OutputConsumer} to which track data and samples are pushed.
     * @return A new instance.
     * @throws IllegalArgumentException If an invalid name is provided.
     */
    @NonNull
    public static MediaParser createByName(
            @NonNull @ParserName String name, @NonNull OutputConsumer outputConsumer) {
        String[] nameAsArray = new String[] {name};
        assertValidNames(nameAsArray);
        return new MediaParser(outputConsumer, /* sniff= */ false, name);
    }

    /**
     * Creates an instance whose backing parser will be selected by sniffing the content during the
     * first {@link #advance} call. Parser implementations will sniff the content in order of
     * appearance in {@code parserNames}.
     *
     * @param outputConsumer The {@link OutputConsumer} to which extracted data is output.
     * @param parserNames The names of the parsers to sniff the content with. If empty, a default
     *     array of names is used.
     * @return A new instance.
     */
    @NonNull
    public static MediaParser create(
            @NonNull OutputConsumer outputConsumer, @NonNull @ParserName String... parserNames) {
        assertValidNames(parserNames);
        if (parserNames.length == 0) {
            parserNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]);
        }
        return new MediaParser(outputConsumer, /* sniff= */ true, parserNames);
    }

    // Misc static methods.

    /**
     * Returns an immutable list with the names of the parsers that are suitable for container
     * formats with the given {@link MediaFormat}.
     *
     * <p>A parser supports a {@link MediaFormat} if the mime type associated with {@link
     * MediaFormat#KEY_MIME} corresponds to the supported container format.
     *
     * @param mediaFormat The {@link MediaFormat} to check support for.
     * @return The parser names that support the given {@code mediaFormat}, or the list of all
     *     parsers available if no container specific format information is provided.
     */
    @NonNull
    @ParserName
    public static List<String> getParserNames(@NonNull MediaFormat mediaFormat) {
        String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
        mimeType = mimeType == null ? null : Util.toLowerInvariant(mimeType.trim());
        if (TextUtils.isEmpty(mimeType)) {
            // No MIME type provided. Return all.
            return Collections.unmodifiableList(
                    new ArrayList<>(EXTRACTOR_FACTORIES_BY_NAME.keySet()));
        }
        ArrayList<String> result = new ArrayList<>();
        switch (mimeType) {
            case "video/x-matroska":
            case "audio/x-matroska":
            case "video/x-webm":
            case "audio/x-webm":
                result.add(PARSER_NAME_MATROSKA);
                break;
            case "video/mp4":
            case "audio/mp4":
            case "application/mp4":
                result.add(PARSER_NAME_MP4);
                result.add(PARSER_NAME_FMP4);
                break;
            case "audio/mpeg":
                result.add(PARSER_NAME_MP3);
                break;
            case "audio/aac":
                result.add(PARSER_NAME_ADTS);
                break;
            case "audio/ac3":
                result.add(PARSER_NAME_AC3);
                break;
            case "video/mp2t":
            case "audio/mp2t":
                result.add(PARSER_NAME_TS);
                break;
            case "video/x-flv":
                result.add(PARSER_NAME_FLV);
                break;
            case "video/ogg":
            case "audio/ogg":
            case "application/ogg":
                result.add(PARSER_NAME_OGG);
                break;
            case "video/mp2p":
            case "video/mp1s":
                result.add(PARSER_NAME_PS);
                break;
            case "audio/vnd.wave":
            case "audio/wav":
            case "audio/wave":
            case "audio/x-wav":
                result.add(PARSER_NAME_WAV);
                break;
            case "audio/amr":
                result.add(PARSER_NAME_AMR);
                break;
            case "audio/ac4":
                result.add(PARSER_NAME_AC4);
                break;
            case "audio/flac":
            case "audio/x-flac":
                result.add(PARSER_NAME_FLAC);
                break;
            default:
                // No parsers support the given mime type. Do nothing.
                break;
        }
        return Collections.unmodifiableList(result);
    }

    // Private fields.

    private final Map<String, Object> mParserParameters;
    private final OutputConsumer mOutputConsumer;
    private final String[] mParserNamesPool;
    private final PositionHolder mPositionHolder;
    private final InputReadingDataReader mExoDataReader;
    private final DataReaderAdapter mScratchDataReaderAdapter;
    private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter;
    @Nullable private final Constructor<DrmInitData.SchemeInitData> mSchemeInitDataConstructor;
    private String mParserName;
    private Extractor mExtractor;
    private ExtractorInput mExtractorInput;
    private boolean mPendingExtractorInit;
    private long mPendingSeekPosition;
    private long mPendingSeekTimeMicros;
    private boolean mLoggedSchemeInitDataCreationException;

    // Public methods.

    /**
     * Sets parser-specific parameters which allow customizing behavior.
     *
     * <p>Must be called before the first call to {@link #advance}.
     *
     * @param parameterName The name of the parameter to set. See {@code PARAMETER_*} constants for
     *     documentation on possible values.
     * @param value The value to set for the given {@code parameterName}. See {@code PARAMETER_*}
     *     constants for documentation on the expected types.
     * @return This instance, for convenience.
     * @throws IllegalStateException If called after calling {@link #advance} on the same instance.
     */
    @NonNull
    public MediaParser setParameter(
            @NonNull @ParameterName String parameterName, @NonNull Object value) {
        if (mExtractor != null) {
            throw new IllegalStateException(
                    "setParameters() must be called before the first advance() call.");
        }
        Class expectedType = EXPECTED_TYPE_BY_PARAMETER_NAME.get(parameterName);
        // Ignore parameter names that are not contained in the map, in case the client is passing
        // a parameter that is being added in a future version of this library.
        if (expectedType != null && !expectedType.isInstance(value)) {
            throw new IllegalArgumentException(
                    parameterName
                            + " expects a "
                            + expectedType.getSimpleName()
                            + " but a "
                            + value.getClass().getSimpleName()
                            + " was passed.");
        }
        if (PARAMETER_TS_MODE.equals(parameterName)
                && !TS_MODE_SINGLE_PMT.equals(value)
                && !TS_MODE_HLS.equals(value)
                && !TS_MODE_MULTI_PMT.equals(value)) {
            throw new IllegalArgumentException(PARAMETER_TS_MODE + " does not accept: " + value);
        }
        mParserParameters.put(parameterName, value);
        return this;
    }

    /**
     * Returns whether the given {@code parameterName} is supported by this parser.
     *
     * @param parameterName The parameter name to check support for. One of the {@code PARAMETER_*}
     *     constants.
     * @return Whether the given {@code parameterName} is supported.
     */
    public boolean supportsParameter(@NonNull @ParameterName String parameterName) {
        return EXPECTED_TYPE_BY_PARAMETER_NAME.containsKey(parameterName);
    }

    /**
     * Returns the name of the backing parser implementation.
     *
     * <p>If this instance was creating using {@link #createByName}, the provided name is returned.
     * If this instance was created using {@link #create}, this method will return {@link
     * #PARSER_NAME_UNKNOWN} until the first call to {@link #advance}, after which the name of the
     * backing parser implementation is returned.
     *
     * @return The name of the backing parser implementation, or null if the backing parser
     *     implementation has not yet been selected.
     */
    @NonNull
    @ParserName
    public String getParserName() {
        return mParserName;
    }

    /**
     * Makes progress in the extraction of the input media stream, unless the end of the input has
     * been reached.
     *
     * <p>This method will block until some progress has been made.
     *
     * <p>If this instance was created using {@link #create}. the first call to this method will
     * sniff the content with the parsers with the provided names.
     *
     * @param seekableInputReader The {@link SeekableInputReader} from which to obtain the media
     *     container data.
     * @return Whether there is any data left to extract. Returns false if the end of input has been
     *     reached.
     * @throws IOException If an error occurs while reading from the {@link SeekableInputReader}.
     * @throws UnrecognizedInputFormatException If the format cannot be recognized by any of the
     *     underlying parser implementations.
     */
    public boolean advance(@NonNull SeekableInputReader seekableInputReader) throws IOException {
        if (mExtractorInput == null) {
            // TODO: For efficiency, the same implementation should be used, by providing a
            // clearBuffers() method, or similar.
            mExtractorInput =
                    new DefaultExtractorInput(
                            mExoDataReader,
                            seekableInputReader.getPosition(),
                            seekableInputReader.getLength());
        }
        mExoDataReader.mInputReader = seekableInputReader;

        // TODO: Apply parameters when creating extractor instances.
        if (mExtractor == null) {
            if (!mParserName.equals(PARSER_NAME_UNKNOWN)) {
                mExtractor = createExtractor(mParserName);
                mExtractor.init(new ExtractorOutputAdapter());
            } else {
                for (String parserName : mParserNamesPool) {
                    Extractor extractor = createExtractor(parserName);
                    try {
                        if (extractor.sniff(mExtractorInput)) {
                            mParserName = parserName;
                            mExtractor = extractor;
                            mPendingExtractorInit = true;
                            break;
                        }
                    } catch (EOFException e) {
                        // Do nothing.
                    } finally {
                        mExtractorInput.resetPeekPosition();
                    }
                }
                if (mExtractor == null) {
                    throw UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
                }
                return true;
            }
        }

        if (mPendingExtractorInit) {
            mExtractor.init(new ExtractorOutputAdapter());
            mPendingExtractorInit = false;
        }
        if (isPendingSeek()) {
            mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeMicros);
            removePendingSeek();
        }

        mPositionHolder.position = seekableInputReader.getPosition();
        int result;
        try {
            result = mExtractor.read(mExtractorInput, mPositionHolder);
        } catch (ParserException e) {
            throw new ParsingException(e);
        }
        if (result == Extractor.RESULT_END_OF_INPUT) {
            return false;
        }
        if (result == Extractor.RESULT_SEEK) {
            mExtractorInput = null;
            seekableInputReader.seekToPosition(mPositionHolder.position);
        }
        return true;
    }

    /**
     * Seeks within the media container being extracted.
     *
     * <p>{@link SeekPoint SeekPoints} can be obtained from the {@link SeekMap} passed to {@link
     * OutputConsumer#onSeekMapFound(SeekMap)}.
     *
     * <p>Following a call to this method, the {@link InputReader} passed to the next invocation of
     * {@link #advance} must provide data starting from {@link SeekPoint#position} in the stream.
     *
     * @param seekPoint The {@link SeekPoint} to seek to.
     */
    public void seek(@NonNull SeekPoint seekPoint) {
        if (mExtractor == null) {
            mPendingSeekPosition = seekPoint.position;
            mPendingSeekTimeMicros = seekPoint.timeMicros;
        } else {
            mExtractor.seek(seekPoint.position, seekPoint.timeMicros);
        }
    }

    /**
     * Releases any acquired resources.
     *
     * <p>After calling this method, this instance becomes unusable and no other methods should be
     * invoked.
     */
    public void release() {
        // TODO: Dump media metrics here.
        mExtractorInput = null;
        mExtractor = null;
    }

    // Private methods.

    private MediaParser(OutputConsumer outputConsumer, boolean sniff, String... parserNamesPool) {
        mParserParameters = new HashMap<>();
        mOutputConsumer = outputConsumer;
        mParserNamesPool = parserNamesPool;
        mParserName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0];
        mPositionHolder = new PositionHolder();
        mExoDataReader = new InputReadingDataReader();
        removePendingSeek();
        mScratchDataReaderAdapter = new DataReaderAdapter();
        mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter();
        mSchemeInitDataConstructor = getSchemeInitDataConstructor();
    }

    private boolean isPendingSeek() {
        return mPendingSeekPosition >= 0;
    }

    private void removePendingSeek() {
        mPendingSeekPosition = -1;
        mPendingSeekTimeMicros = -1;
    }

    private Extractor createExtractor(String parserName) {
        int flags = 0;
        switch (parserName) {
            case PARSER_NAME_MATROSKA:
                flags =
                        getBooleanParameter(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING)
                                ? MatroskaExtractor.FLAG_DISABLE_SEEK_FOR_CUES
                                : 0;
                return new MatroskaExtractor(flags);
            case PARSER_NAME_FMP4:
                flags |=
                        getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS)
                                ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_MP4_IGNORE_TFDT_BOX)
                                ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES)
                                ? FragmentedMp4Extractor
                                        .FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
                                : 0;
                return new FragmentedMp4Extractor(flags);
            case PARSER_NAME_MP4:
                flags |=
                        getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS)
                                ? Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
                                : 0;
                return new Mp4Extractor(flags);
            case PARSER_NAME_MP3:
                flags |=
                        getBooleanParameter(PARAMETER_MP3_DISABLE_ID3)
                                ? Mp3Extractor.FLAG_DISABLE_ID3_METADATA
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_MP3_ENABLE_CBR_SEEKING)
                                ? Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
                                : 0;
                // TODO: Add index seeking once we update the ExoPlayer version.
                return new Mp3Extractor(flags);
            case PARSER_NAME_ADTS:
                flags |=
                        getBooleanParameter(PARAMETER_ADTS_ENABLE_CBR_SEEKING)
                                ? AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
                                : 0;
                return new AdtsExtractor(flags);
            case PARSER_NAME_AC3:
                return new Ac3Extractor();
            case PARSER_NAME_TS:
                flags |=
                        getBooleanParameter(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES)
                                ? DefaultTsPayloadReaderFactory.FLAG_ALLOW_NON_IDR_KEYFRAMES
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_TS_DETECT_ACCESS_UNITS)
                                ? DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS)
                                ? DefaultTsPayloadReaderFactory.FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_TS_IGNORE_AAC_STREAM)
                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_TS_IGNORE_AVC_STREAM)
                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM
                                : 0;
                flags |=
                        getBooleanParameter(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM)
                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_SPLICE_INFO_STREAM
                                : 0;
                String tsMode = getStringParameter(PARAMETER_TS_MODE, TS_MODE_SINGLE_PMT);
                int hlsMode =
                        TS_MODE_SINGLE_PMT.equals(tsMode)
                                ? TsExtractor.MODE_SINGLE_PMT
                                : TS_MODE_HLS.equals(tsMode)
                                        ? TsExtractor.MODE_HLS
                                        : TsExtractor.MODE_MULTI_PMT;
                return new TsExtractor(hlsMode, flags);
            case PARSER_NAME_FLV:
                return new FlvExtractor();
            case PARSER_NAME_OGG:
                return new OggExtractor();
            case PARSER_NAME_PS:
                return new PsExtractor();
            case PARSER_NAME_WAV:
                return new WavExtractor();
            case PARSER_NAME_AMR:
                flags |=
                        getBooleanParameter(PARAMETER_AMR_ENABLE_CBR_SEEKING)
                                ? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
                                : 0;
                return new AmrExtractor(flags);
            case PARSER_NAME_AC4:
                return new Ac4Extractor();
            case PARSER_NAME_FLAC:
                flags |=
                        getBooleanParameter(PARAMETER_FLAC_DISABLE_ID3)
                                ? FlacExtractor.FLAG_DISABLE_ID3_METADATA
                                : 0;
                return new FlacExtractor(flags);
            default:
                // Should never happen.
                throw new IllegalStateException("Unexpected attempt to create: " + parserName);
        }
    }

    private boolean getBooleanParameter(String name) {
        return (boolean) mParserParameters.getOrDefault(name, false);
    }

    private String getStringParameter(String name, String defaultValue) {
        return (String) mParserParameters.getOrDefault(name, defaultValue);
    }

    // Private classes.

    private static final class InputReadingDataReader implements DataReader {

        public InputReader mInputReader;

        @Override
        public int read(byte[] buffer, int offset, int readLength) throws IOException {
            return mInputReader.read(buffer, offset, readLength);
        }
    }

    private final class MediaParserDrmInitData extends DrmInitData {

        private final SchemeInitData[] mSchemeDatas;

        private MediaParserDrmInitData(com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData)
                throws IllegalAccessException, InstantiationException, InvocationTargetException {
            mSchemeDatas = new SchemeInitData[exoDrmInitData.schemeDataCount];
            for (int i = 0; i < mSchemeDatas.length; i++) {
                mSchemeDatas[i] = toFrameworkSchemeInitData(exoDrmInitData.get(i));
            }
        }

        @Override
        @Nullable
        public SchemeInitData get(UUID schemeUuid) {
            for (SchemeInitData schemeInitData : mSchemeDatas) {
                if (schemeInitData.uuid.equals(schemeUuid)) {
                    return schemeInitData;
                }
            }
            return null;
        }

        @Override
        public SchemeInitData getSchemeInitDataAt(int index) {
            return mSchemeDatas[index];
        }

        @Override
        public int getSchemeInitDataCount() {
            return mSchemeDatas.length;
        }

        private DrmInitData.SchemeInitData toFrameworkSchemeInitData(SchemeData exoSchemeData)
                throws IllegalAccessException, InvocationTargetException, InstantiationException {
            return mSchemeInitDataConstructor.newInstance(
                    exoSchemeData.uuid, exoSchemeData.mimeType, exoSchemeData.data);
        }
    }

    private final class ExtractorOutputAdapter implements ExtractorOutput {

        private final SparseArray<TrackOutput> mTrackOutputAdapters;
        private boolean mTracksEnded;

        private ExtractorOutputAdapter() {
            mTrackOutputAdapters = new SparseArray<>();
        }

        @Override
        public TrackOutput track(int id, int type) {
            TrackOutput trackOutput = mTrackOutputAdapters.get(id);
            if (trackOutput == null) {
                trackOutput = new TrackOutputAdapter(mTrackOutputAdapters.size());
                mTrackOutputAdapters.put(id, trackOutput);
            }
            return trackOutput;
        }

        @Override
        public void endTracks() {
            mOutputConsumer.onTrackCountFound(mTrackOutputAdapters.size());
        }

        @Override
        public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
            mOutputConsumer.onSeekMapFound(new SeekMap(exoplayerSeekMap));
        }
    }

    private class TrackOutputAdapter implements TrackOutput {

        private final int mTrackIndex;

        private TrackOutputAdapter(int trackIndex) {
            mTrackIndex = trackIndex;
        }

        @Override
        public void format(Format format) {
            mOutputConsumer.onTrackDataFound(
                    mTrackIndex,
                    new TrackData(
                            toMediaFormat(format), toFrameworkDrmInitData(format.drmInitData)));
        }

        @Override
        public int sampleData(
                DataReader input,
                int length,
                boolean allowEndOfInput,
                @SampleDataPart int sampleDataPart)
                throws IOException {
            mScratchDataReaderAdapter.setDataReader(input, length);
            long positionBeforeReading = mScratchDataReaderAdapter.getPosition();
            mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchDataReaderAdapter);
            return (int) (mScratchDataReaderAdapter.getPosition() - positionBeforeReading);
        }

        @Override
        public void sampleData(
                ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) {
            mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
            try {
                mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchParsableByteArrayAdapter);
            } catch (IOException e) {
                // Unexpected.
                throw new RuntimeException(e);
            }
        }

        @Override
        public void sampleMetadata(
                long timeUs, int flags, int size, int offset, CryptoData encryptionData) {
            mOutputConsumer.onSampleCompleted(
                    mTrackIndex, timeUs, flags, size, offset, toCryptoInfo(encryptionData));
        }
    }

    private static final class DataReaderAdapter implements InputReader {

        private DataReader mDataReader;
        private int mCurrentPosition;
        private long mLength;

        public void setDataReader(DataReader dataReader, long length) {
            mDataReader = dataReader;
            mCurrentPosition = 0;
            mLength = length;
        }

        // Input implementation.

        @Override
        public int read(byte[] buffer, int offset, int readLength) throws IOException {
            int readBytes = 0;
            readBytes = mDataReader.read(buffer, offset, readLength);
            mCurrentPosition += readBytes;
            return readBytes;
        }

        @Override
        public long getPosition() {
            return mCurrentPosition;
        }

        @Override
        public long getLength() {
            return mLength - mCurrentPosition;
        }
    }

    private static final class ParsableByteArrayAdapter implements InputReader {

        private ParsableByteArray mByteArray;
        private long mLength;
        private int mCurrentPosition;

        public void resetWithByteArray(ParsableByteArray byteArray, long length) {
            mByteArray = byteArray;
            mCurrentPosition = 0;
            mLength = length;
        }

        // Input implementation.

        @Override
        public int read(byte[] buffer, int offset, int readLength) {
            mByteArray.readBytes(buffer, offset, readLength);
            mCurrentPosition += readLength;
            return readLength;
        }

        @Override
        public long getPosition() {
            return mCurrentPosition;
        }

        @Override
        public long getLength() {
            return mLength - mCurrentPosition;
        }
    }

    /** Creates extractor instances. */
    private interface ExtractorFactory {

        /** Returns a new extractor instance. */
        Extractor createInstance();
    }

    // Private static methods.

    private static MediaFormat toMediaFormat(Format format) {
        MediaFormat result = new MediaFormat();
        setOptionalMediaFormatInt(result, MediaFormat.KEY_BIT_RATE, format.bitrate);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_CHANNEL_COUNT, format.channelCount);

        ColorInfo colorInfo = format.colorInfo;
        if (colorInfo != null) {
            setOptionalMediaFormatInt(
                    result, MediaFormat.KEY_COLOR_TRANSFER, colorInfo.colorTransfer);
            setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_RANGE, colorInfo.colorRange);
            setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_STANDARD, colorInfo.colorSpace);

            if (format.colorInfo.hdrStaticInfo != null) {
                result.setByteBuffer(
                        MediaFormat.KEY_HDR_STATIC_INFO,
                        ByteBuffer.wrap(format.colorInfo.hdrStaticInfo));
            }
        }

        setOptionalMediaFormatString(result, MediaFormat.KEY_MIME, format.sampleMimeType);
        setOptionalMediaFormatString(result, MediaFormat.KEY_CODECS_STRING, format.codecs);
        if (format.frameRate != Format.NO_VALUE) {
            result.setFloat(MediaFormat.KEY_FRAME_RATE, format.frameRate);
        }
        setOptionalMediaFormatInt(result, MediaFormat.KEY_WIDTH, format.width);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_HEIGHT, format.height);

        List<byte[]> initData = format.initializationData;
        for (int i = 0; i < initData.size(); i++) {
            result.setByteBuffer("csd-" + i, ByteBuffer.wrap(initData.get(i)));
        }
        setPcmEncoding(format, result);
        setOptionalMediaFormatString(result, MediaFormat.KEY_LANGUAGE, format.language);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_MAX_INPUT_SIZE, format.maxInputSize);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_ROTATION, format.rotationDegrees);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_SAMPLE_RATE, format.sampleRate);
        setOptionalMediaFormatInt(
                result, MediaFormat.KEY_CAPTION_SERVICE_NUMBER, format.accessibilityChannel);

        int selectionFlags = format.selectionFlags;
        result.setInteger(
                MediaFormat.KEY_IS_AUTOSELECT, selectionFlags & C.SELECTION_FLAG_AUTOSELECT);
        result.setInteger(MediaFormat.KEY_IS_DEFAULT, selectionFlags & C.SELECTION_FLAG_DEFAULT);
        result.setInteger(
                MediaFormat.KEY_IS_FORCED_SUBTITLE, selectionFlags & C.SELECTION_FLAG_FORCED);

        setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_DELAY, format.encoderDelay);
        setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_PADDING, format.encoderPadding);

        if (format.pixelWidthHeightRatio != Format.NO_VALUE && format.pixelWidthHeightRatio != 0) {
            int parWidth = 1;
            int parHeight = 1;
            if (format.pixelWidthHeightRatio < 1.0f) {
                parHeight = 1 << 30;
                parWidth = (int) (format.pixelWidthHeightRatio * parHeight);
            } else if (format.pixelWidthHeightRatio > 1.0f) {
                parWidth = 1 << 30;
                parHeight = (int) (parWidth / format.pixelWidthHeightRatio);
            }
            result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, parWidth);
            result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, parHeight);
            result.setFloat("pixel-width-height-ratio-float", format.pixelWidthHeightRatio);
        }
        if (format.drmInitData != null) {
            // The crypto mode is propagated along with sample metadata. We also include it in the
            // format for convenient use from ExoPlayer.
            result.setString("crypto-mode-fourcc", format.drmInitData.schemeType);
        }
        // LACK OF SUPPORT FOR:
        //    format.containerMimeType;
        //    format.id;
        //    format.metadata;
        //    format.stereoMode;
        return result;
    }

    private static void setPcmEncoding(Format format, MediaFormat result) {
        int exoPcmEncoding = format.pcmEncoding;
        setOptionalMediaFormatInt(result, "exo-pcm-encoding", format.pcmEncoding);
        int mediaFormatPcmEncoding;
        switch (exoPcmEncoding) {
            case C.ENCODING_PCM_8BIT:
                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_8BIT;
                break;
            case C.ENCODING_PCM_16BIT:
                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_16BIT;
                break;
            case C.ENCODING_PCM_FLOAT:
                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_FLOAT;
                break;
            default:
                // No matching value. Do nothing.
                return;
        }
        result.setInteger(MediaFormat.KEY_PCM_ENCODING, mediaFormatPcmEncoding);
    }

    private static void setOptionalMediaFormatInt(MediaFormat mediaFormat, String key, int value) {
        if (value != Format.NO_VALUE) {
            mediaFormat.setInteger(key, value);
        }
    }

    private static void setOptionalMediaFormatString(
            MediaFormat mediaFormat, String key, @Nullable String value) {
        if (value != null) {
            mediaFormat.setString(key, value);
        }
    }

    private DrmInitData toFrameworkDrmInitData(
            com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData) {
        try {
            return exoDrmInitData != null && mSchemeInitDataConstructor != null
                    ? new MediaParserDrmInitData(exoDrmInitData)
                    : null;
        } catch (Throwable e) {
            if (!mLoggedSchemeInitDataCreationException) {
                mLoggedSchemeInitDataCreationException = true;
                Log.e(TAG, "Unable to create SchemeInitData instance.");
            }
            return null;
        }
    }

    private static CryptoInfo toCryptoInfo(TrackOutput.CryptoData encryptionData) {
        // TODO: Implement.
        return null;
    }

    /** Returns a new {@link SeekPoint} equivalent to the given {@code exoPlayerSeekPoint}. */
    private static SeekPoint toSeekPoint(
            com.google.android.exoplayer2.extractor.SeekPoint exoPlayerSeekPoint) {
        return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position);
    }

    private static void assertValidNames(@NonNull String[] names) {
        for (String name : names) {
            if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) {
                throw new IllegalArgumentException(
                        "Invalid extractor name: "
                                + name
                                + ". Supported parsers are: "
                                + TextUtils.join(", ", EXTRACTOR_FACTORIES_BY_NAME.keySet())
                                + ".");
            }
        }
    }

    @Nullable
    private static Constructor<DrmInitData.SchemeInitData> getSchemeInitDataConstructor() {
        // TODO: Use constructor statically when available.
        Constructor<DrmInitData.SchemeInitData> constructor;
        try {
            return DrmInitData.SchemeInitData.class.getConstructor(
                    UUID.class, String.class, byte[].class);
        } catch (Throwable e) {
            Log.e(TAG, "Unable to get SchemeInitData constructor.");
            return null;
        }
    }

    // Static initialization.

    static {
        // Using a LinkedHashMap to keep the insertion order when iterating over the keys.
        LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>();
        // Parsers are ordered to match ExoPlayer's DefaultExtractorsFactory extractor ordering,
        // which in turn aims to minimize the chances of incorrect extractor selections.
        extractorFactoriesByName.put(PARSER_NAME_MATROSKA, MatroskaExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_FMP4, FragmentedMp4Extractor::new);
        extractorFactoriesByName.put(PARSER_NAME_MP4, Mp4Extractor::new);
        extractorFactoriesByName.put(PARSER_NAME_MP3, Mp3Extractor::new);
        extractorFactoriesByName.put(PARSER_NAME_ADTS, AdtsExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_AC3, Ac3Extractor::new);
        extractorFactoriesByName.put(PARSER_NAME_TS, TsExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_FLV, FlvExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_OGG, OggExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_PS, PsExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_WAV, WavExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_AMR, AmrExtractor::new);
        extractorFactoriesByName.put(PARSER_NAME_AC4, Ac4Extractor::new);
        extractorFactoriesByName.put(PARSER_NAME_FLAC, FlacExtractor::new);
        EXTRACTOR_FACTORIES_BY_NAME = Collections.unmodifiableMap(extractorFactoriesByName);

        HashMap<String, Class> expectedTypeByParameterName = new HashMap<>();
        expectedTypeByParameterName.put(PARAMETER_ADTS_ENABLE_CBR_SEEKING, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_AMR_ENABLE_CBR_SEEKING, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_FLAC_DISABLE_ID3, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_TFDT_BOX, Boolean.class);
        expectedTypeByParameterName.put(
                PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MP3_DISABLE_ID3, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_CBR_SEEKING, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_INDEX_SEEKING, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_MODE, String.class);
        expectedTypeByParameterName.put(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AAC_STREAM, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AVC_STREAM, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_DETECT_ACCESS_UNITS, Boolean.class);
        expectedTypeByParameterName.put(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, Boolean.class);
        EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
    }
}
