/*
 * Copyright (C) 2008 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.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.text.TextUtils;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MediaMetadataRetriever class provides a unified interface for retrieving
 * frame and meta data from an input media file.
 */
public class MediaMetadataRetriever implements AutoCloseable {

    // borrowed from ExoPlayer
    private static final String[] STANDARD_GENRES = new String[] {
            // These are the official ID3v1 genres.
            "Blues",
            "Classic Rock",
            "Country",
            "Dance",
            "Disco",
            "Funk",
            "Grunge",
            "Hip-Hop",
            "Jazz",
            "Metal",
            "New Age",
            "Oldies",
            "Other",
            "Pop",
            "R&B",
            "Rap",
            "Reggae",
            "Rock",
            "Techno",
            "Industrial",
            "Alternative",
            "Ska",
            "Death Metal",
            "Pranks",
            "Soundtrack",
            "Euro-Techno",
            "Ambient",
            "Trip-Hop",
            "Vocal",
            "Jazz+Funk",
            "Fusion",
            "Trance",
            "Classical",
            "Instrumental",
            "Acid",
            "House",
            "Game",
            "Sound Clip",
            "Gospel",
            "Noise",
            "AlternRock",
            "Bass",
            "Soul",
            "Punk",
            "Space",
            "Meditative",
            "Instrumental Pop",
            "Instrumental Rock",
            "Ethnic",
            "Gothic",
            "Darkwave",
            "Techno-Industrial",
            "Electronic",
            "Pop-Folk",
            "Eurodance",
            "Dream",
            "Southern Rock",
            "Comedy",
            "Cult",
            "Gangsta",
            "Top 40",
            "Christian Rap",
            "Pop/Funk",
            "Jungle",
            "Native American",
            "Cabaret",
            "New Wave",
            "Psychadelic",
            "Rave",
            "Showtunes",
            "Trailer",
            "Lo-Fi",
            "Tribal",
            "Acid Punk",
            "Acid Jazz",
            "Polka",
            "Retro",
            "Musical",
            "Rock & Roll",
            "Hard Rock",
            // These were made up by the authors of Winamp and later added to the ID3 spec.
            "Folk",
            "Folk-Rock",
            "National Folk",
            "Swing",
            "Fast Fusion",
            "Bebob",
            "Latin",
            "Revival",
            "Celtic",
            "Bluegrass",
            "Avantgarde",
            "Gothic Rock",
            "Progressive Rock",
            "Psychedelic Rock",
            "Symphonic Rock",
            "Slow Rock",
            "Big Band",
            "Chorus",
            "Easy Listening",
            "Acoustic",
            "Humour",
            "Speech",
            "Chanson",
            "Opera",
            "Chamber Music",
            "Sonata",
            "Symphony",
            "Booty Bass",
            "Primus",
            "Porn Groove",
            "Satire",
            "Slow Jam",
            "Club",
            "Tango",
            "Samba",
            "Folklore",
            "Ballad",
            "Power Ballad",
            "Rhythmic Soul",
            "Freestyle",
            "Duet",
            "Punk Rock",
            "Drum Solo",
            "A capella",
            "Euro-House",
            "Dance Hall",
            // These were made up by the authors of Winamp but have not been added to the ID3 spec.
            "Goa",
            "Drum & Bass",
            "Club-House",
            "Hardcore",
            "Terror",
            "Indie",
            "BritPop",
            "Afro-Punk",
            "Polsk Punk",
            "Beat",
            "Christian Gangsta Rap",
            "Heavy Metal",
            "Black Metal",
            "Crossover",
            "Contemporary Christian",
            "Christian Rock",
            "Merengue",
            "Salsa",
            "Thrash Metal",
            "Anime",
            "Jpop",
            "Synthpop"
    };

    static {
        System.loadLibrary("media_jni");
        native_init();
    }

    // The field below is accessed by native methods
    @SuppressWarnings("unused")
    private long mNativeContext;

    private static final int EMBEDDED_PICTURE_TYPE_ANY = 0xFFFF;

    public MediaMetadataRetriever() {
        native_setup();
    }

    /**
     * Sets the data source (file pathname) to use. Call this
     * method before the rest of the methods in this class. This method may be
     * time-consuming.
     *
     * @param path The path, or the URI (doesn't support streaming source currently)
     * of the input media file.
     * @throws IllegalArgumentException If the path is invalid.
     */
    public void setDataSource(String path) throws IllegalArgumentException {
        if (path == null) {
            throw new IllegalArgumentException("null path");
        }

        final Uri uri = Uri.parse(path);
        final String scheme = uri.getScheme();
        if ("file".equals(scheme)) {
            path = uri.getPath();
        } else if (scheme != null) {
            setDataSource(path, new HashMap<String, String>());
            return;
        }

        try (FileInputStream is = new FileInputStream(path)) {
            FileDescriptor fd = is.getFD();
            setDataSource(fd, 0, 0x7ffffffffffffffL);
        } catch (FileNotFoundException fileEx) {
            throw new IllegalArgumentException(path + " does not exist");
        } catch (IOException ioEx) {
            throw new IllegalArgumentException("couldn't open " + path);
        }
    }

    /**
     * Sets the data source (URI) to use. Call this
     * method before the rest of the methods in this class. This method may be
     * time-consuming.
     *
     * @param uri The URI of the input media.
     * @param headers the headers to be sent together with the request for the data
     * @throws IllegalArgumentException If the URI is invalid.
     */
    public void setDataSource(String uri,  Map<String, String> headers)
            throws IllegalArgumentException {
        int i = 0;
        String[] keys = new String[headers.size()];
        String[] values = new String[headers.size()];
        for (Map.Entry<String, String> entry: headers.entrySet()) {
            keys[i] = entry.getKey();
            values[i] = entry.getValue();
            ++i;
        }

        _setDataSource(
                MediaHTTPService.createHttpServiceBinderIfNecessary(uri),
                uri,
                keys,
                values);
    }

    private native void _setDataSource(
        IBinder httpServiceBinder, String uri, String[] keys, String[] values)
        throws IllegalArgumentException;

    /**
     * Sets the data source (FileDescriptor) to use.  It is the caller's
     * responsibility to close the file descriptor. It is safe to do so as soon
     * as this call returns. Call this method before the rest of the methods in
     * this class. This method may be time-consuming.
     *
     * @param fd the FileDescriptor for the file you want to play
     * @param offset the offset into the file where the data to be played starts,
     * in bytes. It must be non-negative
     * @param length the length in bytes of the data to be played. It must be
     * non-negative.
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public native void setDataSource(FileDescriptor fd, long offset, long length)
            throws IllegalArgumentException;

    /**
     * Sets the data source (FileDescriptor) to use. It is the caller's
     * responsibility to close the file descriptor. It is safe to do so as soon
     * as this call returns. Call this method before the rest of the methods in
     * this class. This method may be time-consuming.
     *
     * @param fd the FileDescriptor for the file you want to play
     * @throws IllegalArgumentException if the FileDescriptor is invalid
     */
    public void setDataSource(FileDescriptor fd)
            throws IllegalArgumentException {
        // intentionally less than LONG_MAX
        setDataSource(fd, 0, 0x7ffffffffffffffL);
    }

    /**
     * Sets the data source as a content Uri. Call this method before
     * the rest of the methods in this class. This method may be time-consuming.
     *
     * @param context the Context to use when resolving the Uri
     * @param uri the Content URI of the data you want to play
     * @throws IllegalArgumentException if the Uri is invalid
     * @throws SecurityException if the Uri cannot be used due to lack of
     * permission.
     */
    public void setDataSource(Context context, Uri uri)
        throws IllegalArgumentException, SecurityException {
        if (uri == null) {
            throw new IllegalArgumentException("null uri");
        }

        String scheme = uri.getScheme();
        if(scheme == null || scheme.equals("file")) {
            setDataSource(uri.getPath());
            return;
        }

        AssetFileDescriptor fd = null;
        try {
            ContentResolver resolver = context.getContentResolver();
            try {
                fd = resolver.openAssetFileDescriptor(uri, "r");
            } catch(FileNotFoundException e) {
                throw new IllegalArgumentException("could not access " + uri);
            }
            if (fd == null) {
                throw new IllegalArgumentException("got null FileDescriptor for " + uri);
            }
            FileDescriptor descriptor = fd.getFileDescriptor();
            if (!descriptor.valid()) {
                throw new IllegalArgumentException("got invalid FileDescriptor for " + uri);
            }
            // Note: using getDeclaredLength so that our behavior is the same
            // as previous versions when the content provider is returning
            // a full file.
            if (fd.getDeclaredLength() < 0) {
                setDataSource(descriptor);
            } else {
                setDataSource(descriptor, fd.getStartOffset(), fd.getDeclaredLength());
            }
            return;
        } catch (SecurityException ex) {
        } finally {
            try {
                if (fd != null) {
                    fd.close();
                }
            } catch(IOException ioEx) {
            }
        }
        setDataSource(uri.toString());
    }

    /**
     * Sets the data source (MediaDataSource) to use.
     *
     * @param dataSource the MediaDataSource for the media you want to play
     */
    public void setDataSource(MediaDataSource dataSource)
            throws IllegalArgumentException {
        _setDataSource(dataSource);
    }

    private native void _setDataSource(MediaDataSource dataSource)
          throws IllegalArgumentException;

    private native @Nullable String nativeExtractMetadata(int keyCode);

    /**
     * Call this method after setDataSource(). This method retrieves the
     * meta data value associated with the keyCode.
     *
     * The keyCode currently supported is listed below as METADATA_XXX
     * constants. With any other value, it returns a null pointer.
     *
     * @param keyCode One of the constants listed below at the end of the class.
     * @return The meta data value associate with the given keyCode on success;
     * null on failure.
     */
    public @Nullable String extractMetadata(int keyCode) {
        String meta = nativeExtractMetadata(keyCode);
        if (keyCode == METADATA_KEY_GENRE) {
            // translate numeric genre code(s) to human readable
            meta = convertGenreTag(meta);
        }
        return meta;
    }

    /*
     * The id3v2 spec doesn't specify the syntax of the genre tag very precisely, so
     * some assumptions are made. Using one possible interpretation of the id3v2
     * spec, this method converts an id3 genre tag string to a human readable string,
     * as follows:
     * - if the first character of the tag is a digit, the entire tag is assumed to
     *   be an id3v1 numeric genre code. If the tag does not parse to a number, or
     *   the number is outside the range of defined standard genres, it is ignored.
     * - if the tag does not start with a digit, it is assumed to be an id3v2 style
     *   tag consisting of one or more genres, with each genre being either a parenthesized
     *   integer referring to an id3v1 numeric genre code, the special indicators "(CR)" or
     *   "(RX)" (for "Cover" or "Remix", respectively), or a custom genre string. When
     *   a custom genre string is encountered, it is assumed to continue until the end
     *   of the tag, unless it starts with "((" in which case it is assumed to continue
     *   until the next close-parenthesis or the end of the tag. Any parse error in the tag
     *   causes it to be ignored.
     * The human-readable genre string is not localized, and uses the English genre names
     * from the spec.
     */
    private String convertGenreTag(String meta) {
        if (TextUtils.isEmpty(meta)) {
            return null;
        }

        if (Character.isDigit(meta.charAt(0))) {
            // assume a single id3v1-style bare number without any extra characters
            try {
                int genreIndex = Integer.parseInt(meta);
                if (genreIndex >= 0 && genreIndex < STANDARD_GENRES.length) {
                    return STANDARD_GENRES[genreIndex];
                }
            } catch (NumberFormatException e) {
                // ignore and fall through
            }
            return null;
        } else {
            // assume id3v2-style genre tag, with parenthesized numeric genres
            // and/or literal genre strings, possibly more than one per tag.
            StringBuilder genres = null;
            String nextGenre = null;
            while (true) {
                if (!TextUtils.isEmpty(nextGenre)) {
                    if (genres == null) {
                        genres = new StringBuilder();
                    }
                    if (genres.length() != 0) {
                        genres.append(", ");
                    }
                    genres.append(nextGenre);
                    nextGenre = null;
                }
                if (TextUtils.isEmpty(meta)) {
                    // entire tag has been processed.
                    break;
                }
                if (meta.startsWith("(RX)")) {
                    nextGenre = "Remix";
                    meta = meta.substring(4);
                } else if (meta.startsWith("(CR)")) {
                    nextGenre = "Cover";
                    meta = meta.substring(4);
                } else if (meta.startsWith("((")) {
                    // the id3v2 spec says that custom genres that start with a parenthesis
                    // should be "escaped" with another parenthesis, however the spec doesn't
                    // specify escaping parentheses inside the custom string. We'll parse any
                    // such strings until a closing parenthesis is found, or the end of
                    // the tag is reached.
                    int closeParenOffset = meta.indexOf(')');
                    if (closeParenOffset == -1) {
                        // string continues to end of tag
                        nextGenre = meta.substring(1);
                        meta = "";
                    } else {
                        nextGenre = meta.substring(1, closeParenOffset + 1);
                        meta = meta.substring(closeParenOffset + 1);
                    }
                } else if (meta.startsWith("(")) {
                    // should be a parenthesized numeric genre
                    int closeParenOffset = meta.indexOf(')');
                    if (closeParenOffset == -1) {
                        return null;
                    }
                    String genreNumString = meta.substring(1, closeParenOffset);
                    try {
                        int genreIndex = Integer.parseInt(genreNumString.toString());
                        if (genreIndex >= 0 && genreIndex < STANDARD_GENRES.length) {
                            nextGenre = STANDARD_GENRES[genreIndex];
                        } else {
                            return null;
                        }
                    } catch (NumberFormatException e) {
                        return null;
                    }
                    meta = meta.substring(closeParenOffset + 1);
                } else {
                    // custom genre
                    nextGenre = meta;
                    meta = "";
                }
            }
            return genres == null || genres.length() == 0 ? null : genres.toString();
        }
    }

    /**
     * This method is similar to {@link #getFrameAtTime(long, int, BitmapParams)}
     * except that the device will choose the actual {@link Bitmap.Config} to use.
     *
     * @param timeUs The time position where the frame will be retrieved.
     * When retrieving the frame at the given time position, there is no
     * guarantee that the data source has a frame located at the position.
     * When this happens, a frame nearby will be returned. If timeUs is
     * negative, time position and option will ignored, and any frame
     * that the implementation considers as representative may be returned.
     *
     * @param option a hint on how the frame is found. Use
     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp earlier than or the same as timeUs. Use
     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp later than or the same as timeUs. Use
     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp closest to or the same as timeUs. Use
     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
     * or may not be a sync frame but is closest to or the same as timeUs.
     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
     * to the other options if there is no sync frame located at timeUs.
     *
     * @return A Bitmap containing a representative video frame, which can be null,
     *         if such a frame cannot be retrieved. {@link Bitmap#getConfig()} can
     *         be used to query the actual {@link Bitmap.Config}.
     *
     * @see #getFrameAtTime(long, int, BitmapParams)
     */
    public @Nullable Bitmap getFrameAtTime(long timeUs, @Option int option) {
        if (option < OPTION_PREVIOUS_SYNC ||
            option > OPTION_CLOSEST) {
            throw new IllegalArgumentException("Unsupported option: " + option);
        }

        return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/, null);
    }

    /**
     * Call this method after setDataSource(). This method finds a
     * representative frame close to the given time position by considering
     * the given option if possible, and returns it as a bitmap.
     *
     * <p>If you don't need a full-resolution
     * frame (for example, because you need a thumbnail image), use
     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
     * method.</p>
     *
     * @param timeUs The time position where the frame will be retrieved.
     * When retrieving the frame at the given time position, there is no
     * guarantee that the data source has a frame located at the position.
     * When this happens, a frame nearby will be returned. If timeUs is
     * negative, time position and option will ignored, and any frame
     * that the implementation considers as representative may be returned.
     *
     * @param option a hint on how the frame is found. Use
     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp earlier than or the same as timeUs. Use
     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp later than or the same as timeUs. Use
     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp closest to or the same as timeUs. Use
     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
     * or may not be a sync frame but is closest to or the same as timeUs.
     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
     * to the other options if there is no sync frame located at timeUs.
     *
     * @param params BitmapParams that controls the returned bitmap config
     *        (such as pixel formats).
     *
     * @return A Bitmap containing a representative video frame, which
     *         can be null, if such a frame cannot be retrieved.
     *
     * @see #getFrameAtTime(long, int)
     */
    public @Nullable Bitmap getFrameAtTime(
            long timeUs, @Option int option, @NonNull BitmapParams params) {
        if (option < OPTION_PREVIOUS_SYNC ||
            option > OPTION_CLOSEST) {
            throw new IllegalArgumentException("Unsupported option: " + option);
        }

        return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/, params);
    }

    /**
     * This method is similar to {@link #getScaledFrameAtTime(long, int, int, int, BitmapParams)}
     * except that the device will choose the actual {@link Bitmap.Config} to use.
     *
     * @param timeUs The time position in microseconds where the frame will be retrieved.
     * When retrieving the frame at the given time position, there is no
     * guarantee that the data source has a frame located at the position.
     * When this happens, a frame nearby will be returned. If timeUs is
     * negative, time position and option will ignored, and any frame
     * that the implementation considers as representative may be returned.
     *
     * @param option a hint on how the frame is found. Use
     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp earlier than or the same as timeUs. Use
     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp later than or the same as timeUs. Use
     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp closest to or the same as timeUs. Use
     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
     * or may not be a sync frame but is closest to or the same as timeUs.
     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
     * to the other options if there is no sync frame located at timeUs.
     *
     * @param dstWidth expected output bitmap width
     * @param dstHeight expected output bitmap height
     * @return A Bitmap containing a representative video frame, which can be null,
     *         if such a frame cannot be retrieved. {@link Bitmap#getConfig()} can
     *         be used to query the actual {@link Bitmap.Config}.
     * @throws IllegalArgumentException if passed in invalid option or width by height
     *         is less than or equal to 0.
     * @see #getScaledFrameAtTime(long, int, int, int, BitmapParams)
     */
    public @Nullable Bitmap getScaledFrameAtTime(long timeUs, @Option int option,
            @IntRange(from=1) int dstWidth, @IntRange(from=1) int dstHeight) {
        validate(option, dstWidth, dstHeight);
        return _getFrameAtTime(timeUs, option, dstWidth, dstHeight, null);
    }

    /**
     * Retrieve a video frame near a given timestamp scaled to a desired size.
     * Call this method after setDataSource(). This method finds a representative
     * frame close to the given time position by considering the given option
     * if possible, and returns it as a bitmap with same aspect ratio as the source
     * while scaling it so that it fits into the desired size of dst_width by dst_height.
     * This is useful for generating a thumbnail for an input data source or just to
     * obtain a scaled frame at the given time position.
     *
     * @param timeUs The time position in microseconds where the frame will be retrieved.
     * When retrieving the frame at the given time position, there is no
     * guarantee that the data source has a frame located at the position.
     * When this happens, a frame nearby will be returned. If timeUs is
     * negative, time position and option will ignored, and any frame
     * that the implementation considers as representative may be returned.
     *
     * @param option a hint on how the frame is found. Use
     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp earlier than or the same as timeUs. Use
     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp later than or the same as timeUs. Use
     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
     * that has a timestamp closest to or the same as timeUs. Use
     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
     * or may not be a sync frame but is closest to or the same as timeUs.
     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
     * to the other options if there is no sync frame located at timeUs.
     *
     * @param dstWidth expected output bitmap width
     * @param dstHeight expected output bitmap height
     * @param params BitmapParams that controls the returned bitmap config
     *        (such as pixel formats).
     *
     * @return A Bitmap of size not larger than dstWidth by dstHeight containing a
     *         scaled video frame, which can be null, if such a frame cannot be retrieved.
     * @throws IllegalArgumentException if passed in invalid option or width by height
     *         is less than or equal to 0.
     * @see #getScaledFrameAtTime(long, int, int, int)
     */
    public @Nullable Bitmap getScaledFrameAtTime(long timeUs, @Option int option,
            @IntRange(from=1) int dstWidth, @IntRange(from=1) int dstHeight,
            @NonNull BitmapParams params) {
        validate(option, dstWidth, dstHeight);
        return _getFrameAtTime(timeUs, option, dstWidth, dstHeight, params);
    }

    private void validate(@Option int option, int dstWidth, int dstHeight) {
        if (option < OPTION_PREVIOUS_SYNC || option > OPTION_CLOSEST) {
            throw new IllegalArgumentException("Unsupported option: " + option);
        }
        if (dstWidth <= 0) {
            throw new IllegalArgumentException("Invalid width: " + dstWidth);
        }
        if (dstHeight <= 0) {
            throw new IllegalArgumentException("Invalid height: " + dstHeight);
        }
    }

    /**
     * Call this method after setDataSource(). This method finds a
     * representative frame close to the given time position if possible,
     * and returns it as a bitmap. Call this method if one does not care
     * how the frame is found as long as it is close to the given time;
     * otherwise, please call {@link #getFrameAtTime(long, int)}.
     *
     * <p>If you don't need a full-resolution
     * frame (for example, because you need a thumbnail image), use
     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
     * method.</p>
     *
     * @param timeUs The time position where the frame will be retrieved.
     * When retrieving the frame at the given time position, there is no
     * guarentee that the data source has a frame located at the position.
     * When this happens, a frame nearby will be returned. If timeUs is
     * negative, time position and option will ignored, and any frame
     * that the implementation considers as representative may be returned.
     *
     * @return A Bitmap of size dst_widthxdst_height containing a representative
     *         video frame, which can be null, if such a frame cannot be retrieved.
     *
     * @see #getFrameAtTime(long, int)
     */
    public @Nullable Bitmap getFrameAtTime(long timeUs) {
        return getFrameAtTime(timeUs, OPTION_CLOSEST_SYNC);
    }

    /**
     * Call this method after setDataSource(). This method finds a
     * representative frame at any time position if possible,
     * and returns it as a bitmap. Call this method if one does not
     * care about where the frame is located; otherwise, please call
     * {@link #getFrameAtTime(long)} or {@link #getFrameAtTime(long, int)}
     *
     * <p>If you don't need a full-resolution
     * frame (for example, because you need a thumbnail image), use
     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
     * method.</p>
     *
     * @return A Bitmap containing a representative video frame, which
     *         can be null, if such a frame cannot be retrieved.
     *
     * @see #getFrameAtTime(long)
     * @see #getFrameAtTime(long, int)
     */
    public @Nullable Bitmap getFrameAtTime() {
        return _getFrameAtTime(
                -1, OPTION_CLOSEST_SYNC, -1 /*dst_width*/, -1 /*dst_height*/, null);
    }

    private native Bitmap _getFrameAtTime(
            long timeUs, int option, int width, int height, @Nullable BitmapParams params);

    public static final class BitmapParams {
        private Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
        private Bitmap.Config outActualConfig = Bitmap.Config.ARGB_8888;

        /**
         * Create a default BitmapParams object. By default, it uses {@link Bitmap.Config#ARGB_8888}
         * as the preferred bitmap config.
         */
        public BitmapParams() {}

        /**
         * Set the preferred bitmap config for the decoder to decode into.
         *
         * If not set, or the request cannot be met, the decoder will output
         * in {@link Bitmap.Config#ARGB_8888} config by default.
         *
         * After decode, the actual config used can be retrieved by {@link #getActualConfig()}.
         *
         * @param config the preferred bitmap config to use.
         */
        public void setPreferredConfig(@NonNull Bitmap.Config config) {
            if (config == null) {
                throw new IllegalArgumentException("preferred config can't be null");
            }
            inPreferredConfig = config;
        }

        /**
         * Retrieve the preferred bitmap config in the params.
         *
         * @return the preferred bitmap config.
         */
        public @NonNull Bitmap.Config getPreferredConfig() {
            return inPreferredConfig;
        }

        /**
         * Get the actual bitmap config used to decode the bitmap after the decoding.
         *
         * @return the actual bitmap config used.
         */
        public @NonNull Bitmap.Config getActualConfig() {
            return outActualConfig;
        }
    }

    /**
     * This method retrieves a video frame by its index. It should only be called
     * after {@link #setDataSource}.
     *
     * After the bitmap is returned, you can query the actual parameters that were
     * used to create the bitmap from the {@code BitmapParams} argument, for instance
     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
     *
     * @param frameIndex 0-based index of the video frame. The frame index must be that of
     *        a valid frame. The total number of frames available for retrieval can be queried
     *        via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
     *
     * @throws IllegalStateException if the container doesn't contain video or image sequences.
     * @throws IllegalArgumentException if the requested frame index does not exist.
     *
     * @return A Bitmap containing the requested video frame, or null if the retrieval fails.
     *
     * @see #getFrameAtIndex(int)
     * @see #getFramesAtIndex(int, int, BitmapParams)
     * @see #getFramesAtIndex(int, int)
     */
    public @Nullable Bitmap getFrameAtIndex(int frameIndex, @NonNull BitmapParams params) {
        List<Bitmap> bitmaps = getFramesAtIndex(frameIndex, 1, params);
        return bitmaps.get(0);
    }

    /**
     * This method is similar to {@link #getFrameAtIndex(int, BitmapParams)} except that
     * the default for {@link BitmapParams} will be used.
     *
     * @param frameIndex 0-based index of the video frame. The frame index must be that of
     *        a valid frame. The total number of frames available for retrieval can be queried
     *        via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
     *
     * @throws IllegalStateException if the container doesn't contain video or image sequences.
     * @throws IllegalArgumentException if the requested frame index does not exist.
     *
     * @return A Bitmap containing the requested video frame, or null if the retrieval fails.
     *
     * @see #getFrameAtIndex(int, BitmapParams)
     * @see #getFramesAtIndex(int, int, BitmapParams)
     * @see #getFramesAtIndex(int, int)
     */
    public @Nullable Bitmap getFrameAtIndex(int frameIndex) {
        List<Bitmap> bitmaps = getFramesAtIndex(frameIndex, 1);
        return bitmaps.get(0);
    }

    /**
     * This method retrieves a consecutive set of video frames starting at the
     * specified index. It should only be called after {@link #setDataSource}.
     *
     * If the caller intends to retrieve more than one consecutive video frames,
     * this method is preferred over {@link #getFrameAtIndex(int, BitmapParams)} for efficiency.
     *
     * After the bitmaps are returned, you can query the actual parameters that were
     * used to create the bitmaps from the {@code BitmapParams} argument, for instance
     * to query the bitmap config used for the bitmaps with {@link BitmapParams#getActualConfig}.
     *
     * @param frameIndex 0-based index of the first video frame to retrieve. The frame index
     *        must be that of a valid frame. The total number of frames available for retrieval
     *        can be queried via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
     * @param numFrames number of consecutive video frames to retrieve. Must be a positive
     *        value. The stream must contain at least numFrames frames starting at frameIndex.
     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
     *
     * @throws IllegalStateException if the container doesn't contain video or image sequences.
     * @throws IllegalArgumentException if the frameIndex or numFrames is invalid, or the
     *         stream doesn't contain at least numFrames starting at frameIndex.

     * @return An list of Bitmaps containing the requested video frames. The returned
     *         array could contain less frames than requested if the retrieval fails.
     *
     * @see #getFrameAtIndex(int, BitmapParams)
     * @see #getFrameAtIndex(int)
     * @see #getFramesAtIndex(int, int)
     */
    public @NonNull List<Bitmap> getFramesAtIndex(
            int frameIndex, int numFrames, @NonNull BitmapParams params) {
        return getFramesAtIndexInternal(frameIndex, numFrames, params);
    }

    /**
     * This method is similar to {@link #getFramesAtIndex(int, int, BitmapParams)} except that
     * the default for {@link BitmapParams} will be used.
     *
     * @param frameIndex 0-based index of the first video frame to retrieve. The frame index
     *        must be that of a valid frame. The total number of frames available for retrieval
     *        can be queried via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
     * @param numFrames number of consecutive video frames to retrieve. Must be a positive
     *        value. The stream must contain at least numFrames frames starting at frameIndex.
     *
     * @throws IllegalStateException if the container doesn't contain video or image sequences.
     * @throws IllegalArgumentException if the frameIndex or numFrames is invalid, or the
     *         stream doesn't contain at least numFrames starting at frameIndex.

     * @return An list of Bitmaps containing the requested video frames. The returned
     *         array could contain less frames than requested if the retrieval fails.
     *
     * @see #getFrameAtIndex(int, BitmapParams)
     * @see #getFrameAtIndex(int)
     * @see #getFramesAtIndex(int, int, BitmapParams)
     */
    public @NonNull List<Bitmap> getFramesAtIndex(int frameIndex, int numFrames) {
        return getFramesAtIndexInternal(frameIndex, numFrames, null);
    }

    private @NonNull List<Bitmap> getFramesAtIndexInternal(
            int frameIndex, int numFrames, @Nullable BitmapParams params) {
        if (!"yes".equals(extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO))) {
            throw new IllegalStateException("Does not contail video or image sequences");
        }
        int frameCount = Integer.parseInt(
                extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));
        if (frameIndex < 0 || numFrames < 1
                || frameIndex >= frameCount
                || frameIndex > frameCount - numFrames) {
            throw new IllegalArgumentException("Invalid frameIndex or numFrames: "
                + frameIndex + ", " + numFrames);
        }
        return _getFrameAtIndex(frameIndex, numFrames, params);
    }

    private native @NonNull List<Bitmap> _getFrameAtIndex(
            int frameIndex, int numFrames, @Nullable BitmapParams params);

    /**
     * This method retrieves a still image by its index. It should only be called
     * after {@link #setDataSource}.
     *
     * After the bitmap is returned, you can query the actual parameters that were
     * used to create the bitmap from the {@code BitmapParams} argument, for instance
     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
     *
     * @param imageIndex 0-based index of the image.
     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
     *
     * @throws IllegalStateException if the container doesn't contain still images.
     * @throws IllegalArgumentException if the requested image does not exist.
     *
     * @return the requested still image, or null if the image cannot be retrieved.
     *
     * @see #getImageAtIndex(int)
     * @see #getPrimaryImage(BitmapParams)
     * @see #getPrimaryImage()
     */
    public @Nullable Bitmap getImageAtIndex(int imageIndex, @NonNull BitmapParams params) {
        return getImageAtIndexInternal(imageIndex, params);
    }

    /**
     * @hide
     *
     * This method retrieves the thumbnail image for a still image if it's available.
     * It should only be called after {@link #setDataSource}.
     *
     * @param imageIndex 0-based index of the image, negative value indicates primary image.
     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
     * @param targetSize intended size of one edge (wdith or height) of the thumbnail,
     *                   this is a heuristic for the framework to decide whether the embedded
     *                   thumbnail should be used.
     * @param maxPixels maximum pixels of thumbnail, this is a heuristic for the frameowrk to
     *                  decide whehther the embedded thumnbail (or a downscaled version of it)
     *                  should be used.
     * @return the retrieved thumbnail, or null if no suitable thumbnail is available.
     */
    public native @Nullable Bitmap getThumbnailImageAtIndex(
            int imageIndex, @NonNull BitmapParams params, int targetSize, int maxPixels);

    /**
     * This method is similar to {@link #getImageAtIndex(int, BitmapParams)} except that
     * the default for {@link BitmapParams} will be used.
     *
     * @param imageIndex 0-based index of the image.
     *
     * @throws IllegalStateException if the container doesn't contain still images.
     * @throws IllegalArgumentException if the requested image does not exist.
     *
     * @return the requested still image, or null if the image cannot be retrieved.
     *
     * @see #getImageAtIndex(int, BitmapParams)
     * @see #getPrimaryImage(BitmapParams)
     * @see #getPrimaryImage()
     */
    public @Nullable Bitmap getImageAtIndex(int imageIndex) {
        return getImageAtIndexInternal(imageIndex, null);
    }

    /**
     * This method retrieves the primary image of the media content. It should only
     * be called after {@link #setDataSource}.
     *
     * After the bitmap is returned, you can query the actual parameters that were
     * used to create the bitmap from the {@code BitmapParams} argument, for instance
     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
     *
     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
     *
     * @return the primary image, or null if it cannot be retrieved.
     *
     * @throws IllegalStateException if the container doesn't contain still images.
     *
     * @see #getImageAtIndex(int, BitmapParams)
     * @see #getImageAtIndex(int)
     * @see #getPrimaryImage()
     */
    public @Nullable Bitmap getPrimaryImage(@NonNull BitmapParams params) {
        return getImageAtIndexInternal(-1, params);
    }

    /**
     * This method is similar to {@link #getPrimaryImage(BitmapParams)} except that
     * the default for {@link BitmapParams} will be used.
     *
     * @return the primary image, or null if it cannot be retrieved.
     *
     * @throws IllegalStateException if the container doesn't contain still images.
     *
     * @see #getImageAtIndex(int, BitmapParams)
     * @see #getImageAtIndex(int)
     * @see #getPrimaryImage(BitmapParams)
     */
    public @Nullable Bitmap getPrimaryImage() {
        return getImageAtIndexInternal(-1, null);
    }

    private Bitmap getImageAtIndexInternal(int imageIndex, @Nullable BitmapParams params) {
        if (!"yes".equals(extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE))) {
            throw new IllegalStateException("Does not contail still images");
        }

        String imageCount = extractMetadata(MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT);
        if (imageIndex >= Integer.parseInt(imageCount)) {
            throw new IllegalArgumentException("Invalid image index: " + imageCount);
        }

        return _getImageAtIndex(imageIndex, params);
    }

    private native Bitmap _getImageAtIndex(int imageIndex, @Nullable BitmapParams params);

    /**
     * Call this method after setDataSource(). This method finds the optional
     * graphic or album/cover art associated associated with the data source. If
     * there are more than one pictures, (any) one of them is returned.
     *
     * @return null if no such graphic is found.
     */
    public @Nullable byte[] getEmbeddedPicture() {
        return getEmbeddedPicture(EMBEDDED_PICTURE_TYPE_ANY);
    }

    @UnsupportedAppUsage
    private native byte[] getEmbeddedPicture(int pictureType);

    @Override
    public void close() {
        release();
    }

    /**
     * Call it when one is done with the object. This method releases the memory
     * allocated internally.
     */
    public native void release();
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private native void native_setup();
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private static native void native_init();

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private native final void native_finalize();

    @Override
    protected void finalize() throws Throwable {
        try {
            native_finalize();
        } finally {
            super.finalize();
        }
    }

    /**
     * Option used in method {@link #getFrameAtTime(long, int)} to get a
     * frame at a specified location.
     *
     * @see #getFrameAtTime(long, int)
     */
    /* Do not change these option values without updating their counterparts
     * in include/media/MediaSource.h!
     */
    /**
     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
     * a sync (or key) frame associated with a data source that is located
     * right before or at the given time.
     *
     * @see #getFrameAtTime(long, int)
     */
    public static final int OPTION_PREVIOUS_SYNC    = 0x00;
    /**
     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
     * a sync (or key) frame associated with a data source that is located
     * right after or at the given time.
     *
     * @see #getFrameAtTime(long, int)
     */
    public static final int OPTION_NEXT_SYNC        = 0x01;
    /**
     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
     * a sync (or key) frame associated with a data source that is located
     * closest to (in time) or at the given time.
     *
     * @see #getFrameAtTime(long, int)
     */
    public static final int OPTION_CLOSEST_SYNC     = 0x02;
    /**
     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
     * a frame (not necessarily a key frame) associated with a data source that
     * is located closest to or at the given time.
     *
     * @see #getFrameAtTime(long, int)
     */
    public static final int OPTION_CLOSEST          = 0x03;

    /** @hide */
    @IntDef(flag = true, prefix = { "OPTION_" }, value = {
            OPTION_PREVIOUS_SYNC,
            OPTION_NEXT_SYNC,
            OPTION_CLOSEST_SYNC,
            OPTION_CLOSEST,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Option {}

    /*
     * Do not change these metadata key values without updating their
     * counterparts in include/media/mediametadataretriever.h!
     */
    /**
     * The metadata key to retrieve the numeric string describing the
     * order of the audio data source on its original recording.
     */
    public static final int METADATA_KEY_CD_TRACK_NUMBER = 0;
    /**
     * The metadata key to retrieve the information about the album title
     * of the data source.
     */
    public static final int METADATA_KEY_ALBUM           = 1;
    /**
     * The metadata key to retrieve the information about the artist of
     * the data source.
     */
    public static final int METADATA_KEY_ARTIST          = 2;
    /**
     * The metadata key to retrieve the information about the author of
     * the data source.
     */
    public static final int METADATA_KEY_AUTHOR          = 3;
    /**
     * The metadata key to retrieve the information about the composer of
     * the data source.
     */
    public static final int METADATA_KEY_COMPOSER        = 4;
    /**
     * The metadata key to retrieve the date when the data source was created
     * or modified.
     */
    public static final int METADATA_KEY_DATE            = 5;
    /**
     * The metadata key to retrieve the content type or genre of the data
     * source.
     */
    public static final int METADATA_KEY_GENRE           = 6;
    /**
     * The metadata key to retrieve the data source title.
     */
    public static final int METADATA_KEY_TITLE           = 7;
    /**
     * The metadata key to retrieve the year when the data source was created
     * or modified.
     */
    public static final int METADATA_KEY_YEAR            = 8;
    /**
     * The metadata key to retrieve the playback duration (in ms) of the data source.
     */
    public static final int METADATA_KEY_DURATION        = 9;
    /**
     * The metadata key to retrieve the number of tracks, such as audio, video,
     * text, in the data source, such as a mp4 or 3gpp file.
     */
    public static final int METADATA_KEY_NUM_TRACKS      = 10;
    /**
     * The metadata key to retrieve the information of the writer (such as
     * lyricist) of the data source.
     */
    public static final int METADATA_KEY_WRITER          = 11;
    /**
     * The metadata key to retrieve the mime type of the data source. Some
     * example mime types include: "video/mp4", "audio/mp4", "audio/amr-wb",
     * etc.
     */
    public static final int METADATA_KEY_MIMETYPE        = 12;
    /**
     * The metadata key to retrieve the information about the performers or
     * artist associated with the data source.
     */
    public static final int METADATA_KEY_ALBUMARTIST     = 13;
    /**
     * The metadata key to retrieve the numberic string that describes which
     * part of a set the audio data source comes from.
     */
    public static final int METADATA_KEY_DISC_NUMBER     = 14;
    /**
     * The metadata key to retrieve the music album compilation status.
     */
    public static final int METADATA_KEY_COMPILATION     = 15;
    /**
     * If this key exists the media contains audio content.
     */
    public static final int METADATA_KEY_HAS_AUDIO       = 16;
    /**
     * If this key exists the media contains video content.
     */
    public static final int METADATA_KEY_HAS_VIDEO       = 17;
    /**
     * If the media contains video, this key retrieves its width.
     */
    public static final int METADATA_KEY_VIDEO_WIDTH     = 18;
    /**
     * If the media contains video, this key retrieves its height.
     */
    public static final int METADATA_KEY_VIDEO_HEIGHT    = 19;
    /**
     * This key retrieves the average bitrate (in bits/sec), if available.
     */
    public static final int METADATA_KEY_BITRATE         = 20;
    /**
     * This key retrieves the language code of text tracks, if available.
     * If multiple text tracks present, the return value will look like:
     * "eng:chi"
     * @hide
     */
    public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES      = 21;
    /**
     * If this key exists the media is drm-protected.
     * @hide
     */
    public static final int METADATA_KEY_IS_DRM          = 22;
    /**
     * This key retrieves the location information, if available.
     * The location should be specified according to ISO-6709 standard, under
     * a mp4/3gp box "@xyz". Location with longitude of -90 degrees and latitude
     * of 180 degrees will be retrieved as "+180.0000-90.0000/", for instance.
     */
    public static final int METADATA_KEY_LOCATION        = 23;
    /**
     * This key retrieves the video rotation angle in degrees, if available.
     * The video rotation angle may be 0, 90, 180, or 270 degrees.
     */
    public static final int METADATA_KEY_VIDEO_ROTATION = 24;
    /**
     * This key retrieves the original capture framerate, if it's
     * available. The capture framerate will be a floating point
     * number.
     */
    public static final int METADATA_KEY_CAPTURE_FRAMERATE = 25;
    /**
     * If this key exists the media contains still image content.
     */
    public static final int METADATA_KEY_HAS_IMAGE       = 26;
    /**
     * If the media contains still images, this key retrieves the number
     * of still images.
     */
    public static final int METADATA_KEY_IMAGE_COUNT     = 27;
    /**
     * If the media contains still images, this key retrieves the image
     * index of the primary image.
     */
    public static final int METADATA_KEY_IMAGE_PRIMARY   = 28;
    /**
     * If the media contains still images, this key retrieves the width
     * of the primary image.
     */
    public static final int METADATA_KEY_IMAGE_WIDTH     = 29;
    /**
     * If the media contains still images, this key retrieves the height
     * of the primary image.
     */
    public static final int METADATA_KEY_IMAGE_HEIGHT    = 30;
    /**
     * If the media contains still images, this key retrieves the rotation
     * angle (in degrees clockwise) of the primary image. The image rotation
     * angle must be one of 0, 90, 180, or 270 degrees.
     */
    public static final int METADATA_KEY_IMAGE_ROTATION  = 31;
    /**
     * If the media contains video and this key exists, it retrieves the
     * total number of frames in the video sequence.
     */
    public static final int METADATA_KEY_VIDEO_FRAME_COUNT = 32;

    /**
     * If the media contains EXIF data, this key retrieves the offset value
     * of the data.
     */
    public static final int METADATA_KEY_EXIF_OFFSET = 33;

    /**
     * If the media contains EXIF data, this key retrieves the length of the
     * data.
     */
    public static final int METADATA_KEY_EXIF_LENGTH = 34;

    /**
     * This key retrieves the color standard, if available.
     *
     * @see MediaFormat#COLOR_STANDARD_BT709
     * @see MediaFormat#COLOR_STANDARD_BT601_PAL
     * @see MediaFormat#COLOR_STANDARD_BT601_NTSC
     * @see MediaFormat#COLOR_STANDARD_BT2020
     */
    public static final int METADATA_KEY_COLOR_STANDARD = 35;

    /**
     * This key retrieves the color transfer, if available.
     *
     * @see MediaFormat#COLOR_TRANSFER_LINEAR
     * @see MediaFormat#COLOR_TRANSFER_SDR_VIDEO
     * @see MediaFormat#COLOR_TRANSFER_ST2084
     * @see MediaFormat#COLOR_TRANSFER_HLG
     */
    public static final int METADATA_KEY_COLOR_TRANSFER = 36;

    /**
     * This key retrieves the color range, if available.
     *
     * @see MediaFormat#COLOR_RANGE_LIMITED
     * @see MediaFormat#COLOR_RANGE_FULL
     */
    public static final int METADATA_KEY_COLOR_RANGE    = 37;
    // Add more here...

    /**
     * This key retrieves the sample rate, if available.
     * @hide
     */
    public static final int METADATA_KEY_SAMPLERATE      = 38;

    /**
     * This key retrieves the bits per sample, if available.
     * @hide
     */
    public static final int METADATA_KEY_BITS_PER_SAMPLE = 39;
}
