/*
 * Copyright (C) 2010 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.compat.annotation.UnsupportedAppUsage;
import android.os.Build;

import java.util.ArrayList;
import java.util.List;

/**
 * The EncoderCapabilities class is used to retrieve the
 * capabilities for different video and audio
 * encoders supported on a specific Android platform.
 * {@hide}
 */
public class EncoderCapabilities
{
    private static final String TAG = "EncoderCapabilities";

    /**
     * The VideoEncoderCap class represents a video encoder's
     * supported parameter range in:
     *
     * <ul>
     * <li>Resolution: the frame size (width/height) in pixels;
     * <li>Bit rate: the compressed output bit rate in bits per second;
     * <li>Frame rate: the output number of frames per second.
     * </ul>
     *
     */
    static public class VideoEncoderCap {
        // These are not modifiable externally, thus are public accessible
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final int mCodec;                // @see android.media.MediaRecorder.VideoEncoder
        public final int mMinBitRate;           // min bit rate (bps)
        public final int mMaxBitRate;           // max bit rate (bps)
        public final int mMinFrameRate;         // min frame rate (fps)
        public final int mMaxFrameRate;         // max frame rate (fps)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final int mMinFrameWidth;        // min frame width (pixel)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final int mMaxFrameWidth;        // max frame width (pixel)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final int mMinFrameHeight;       // min frame height (pixel)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final int mMaxFrameHeight;       // max frame height (pixel)

        // Private constructor called by JNI
        private VideoEncoderCap(int codec,
                                int minBitRate, int maxBitRate,
                                int minFrameRate, int maxFrameRate,
                                int minFrameWidth, int maxFrameWidth,
                                int minFrameHeight, int maxFrameHeight) {
            mCodec = codec;
            mMinBitRate = minBitRate;
            mMaxBitRate = maxBitRate;
            mMinFrameRate = minFrameRate;
            mMaxFrameRate = maxFrameRate;
            mMinFrameWidth = minFrameWidth;
            mMaxFrameWidth = maxFrameWidth;
            mMinFrameHeight = minFrameHeight;
            mMaxFrameHeight = maxFrameHeight;
        }
    };

    /**
     * The AudioEncoderCap class represents an audio encoder's
     * parameter range in:
     *
     * <ul>
     * <li>Bit rate: the compressed output bit rate in bits per second;
     * <li>Sample rate: the sampling rate used for recording the audio in samples per second;
     * <li>Number of channels: the number of channels the audio is recorded.
     * </ul>
     *
     */
    static public class AudioEncoderCap {
        // These are not modifiable externally, thus are public accessible
        public final int mCodec;                         // @see android.media.MediaRecorder.AudioEncoder
        public final int mMinChannels, mMaxChannels;     // min and max number of channels
        public final int mMinSampleRate, mMaxSampleRate; // min and max sample rate (hz)
        public final int mMinBitRate, mMaxBitRate;       // min and max bit rate (bps)

        // Private constructor called by JNI
        private AudioEncoderCap(int codec,
                                int minBitRate, int maxBitRate,
                                int minSampleRate, int maxSampleRate,
                                int minChannels, int maxChannels) {
           mCodec = codec;
           mMinBitRate = minBitRate;
           mMaxBitRate = maxBitRate;
           mMinSampleRate = minSampleRate;
           mMaxSampleRate = maxSampleRate;
           mMinChannels = minChannels;
           mMaxChannels = maxChannels;
       }
    };

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

    /**
     * Returns the array of supported output file formats.
     * @see android.media.MediaRecorder.OutputFormat
     */
    public static int[] getOutputFileFormats() {
        int nFormats = native_get_num_file_formats();
        if (nFormats == 0) return null;

        int[] formats = new int[nFormats];
        for (int i = 0; i < nFormats; ++i) {
            formats[i] = native_get_file_format(i);
        }
        return formats;
    }

    /**
     * Returns the capabilities of the supported video encoders.
     * @see android.media.EncoderCapabilities.VideoEncoderCap
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static List<VideoEncoderCap> getVideoEncoders() {
        int nEncoders = native_get_num_video_encoders();
        if (nEncoders == 0) return null;

        List<VideoEncoderCap> encoderList = new ArrayList<VideoEncoderCap>();
        for (int i = 0; i < nEncoders; ++i) {
            encoderList.add(native_get_video_encoder_cap(i));
        }
        return encoderList;
    }

    /**
     * Returns the capabilities of the supported audio encoders.
     * @see android.media.EncoderCapabilities.AudioEncoderCap
     */
    public static List<AudioEncoderCap> getAudioEncoders() {
        int nEncoders = native_get_num_audio_encoders();
        if (nEncoders == 0) return null;

        List<AudioEncoderCap> encoderList = new ArrayList<AudioEncoderCap>();
        for (int i = 0; i < nEncoders; ++i) {
            encoderList.add(native_get_audio_encoder_cap(i));
        }
        return encoderList;
    }


    private EncoderCapabilities() {}  // Don't call me

    // Implemented by JNI
    private static native final void native_init();
    private static native final int native_get_num_file_formats();
    private static native final int native_get_file_format(int index);
    private static native final int native_get_num_video_encoders();
    private static native final VideoEncoderCap native_get_video_encoder_cap(int index);
    private static native final int native_get_num_audio_encoders();
    private static native final AudioEncoderCap native_get_audio_encoder_cap(int index);
}
