/*
 * 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 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
        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
        public final int mMinFrameWidth;        // min frame width (pixel)
        @UnsupportedAppUsage
        public final int mMaxFrameWidth;        // max frame width (pixel)
        @UnsupportedAppUsage
        public final int mMinFrameHeight;       // min frame height (pixel)
        @UnsupportedAppUsage
        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
    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);
}
