/*
 * 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.hardware.Camera;
import android.hardware.Camera.CameraInfo;

/**
 * Retrieves the
 * predefined camcorder profile settings for camcorder applications.
 * These settings are read-only.
 *
 * <p>The compressed output from a recording session with a given
 * CamcorderProfile contains two tracks: one for audio and one for video.
 *
 * <p>Each profile specifies the following set of parameters:
 * <ul>
 * <li> The file output format
 * <li> Video codec format
 * <li> Video bit rate in bits per second
 * <li> Video frame rate in frames per second
 * <li> Video frame width and height,
 * <li> Audio codec format
 * <li> Audio bit rate in bits per second,
 * <li> Audio sample rate
 * <li> Number of audio channels for recording.
 * </ul>
 */
public class CamcorderProfile
{
    // Do not change these values/ordinals without updating their counterpart
    // in include/media/MediaProfiles.h!

    /**
     * Quality level corresponding to the lowest available resolution.
     */
    public static final int QUALITY_LOW  = 0;

    /**
     * Quality level corresponding to the highest available resolution.
     */
    public static final int QUALITY_HIGH = 1;

    /**
     * Quality level corresponding to the qcif (176 x 144) resolution.
     */
    public static final int QUALITY_QCIF = 2;

    /**
     * Quality level corresponding to the cif (352 x 288) resolution.
     */
    public static final int QUALITY_CIF = 3;

    /**
     * Quality level corresponding to the 480p (720 x 480) resolution.
     * Note that the horizontal resolution for 480p can also be other
     * values, such as 640 or 704, instead of 720.
     */
    public static final int QUALITY_480P = 4;

    /**
     * Quality level corresponding to the 720p (1280 x 720) resolution.
     */
    public static final int QUALITY_720P = 5;

    /**
     * Quality level corresponding to the 1080p (1920 x 1080) resolution.
     * Note that the vertical resolution for 1080p can also be 1088,
     * instead of 1080 (used by some vendors to avoid cropping during
     * video playback).
     */
    public static final int QUALITY_1080P = 6;

    /**
     * Quality level corresponding to the QVGA (320x240) resolution.
     */
    public static final int QUALITY_QVGA = 7;

    /**
     * Quality level corresponding to the 2160p (3840x2160) resolution.
     */
    public static final int QUALITY_2160P = 8;

    // Start and end of quality list
    private static final int QUALITY_LIST_START = QUALITY_LOW;
    private static final int QUALITY_LIST_END = QUALITY_2160P;

    /**
     * Time lapse quality level corresponding to the lowest available resolution.
     */
    public static final int QUALITY_TIME_LAPSE_LOW  = 1000;

    /**
     * Time lapse quality level corresponding to the highest available resolution.
     */
    public static final int QUALITY_TIME_LAPSE_HIGH = 1001;

    /**
     * Time lapse quality level corresponding to the qcif (176 x 144) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_QCIF = 1002;

    /**
     * Time lapse quality level corresponding to the cif (352 x 288) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_CIF = 1003;

    /**
     * Time lapse quality level corresponding to the 480p (720 x 480) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_480P = 1004;

    /**
     * Time lapse quality level corresponding to the 720p (1280 x 720) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_720P = 1005;

    /**
     * Time lapse quality level corresponding to the 1080p (1920 x 1088) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_1080P = 1006;

    /**
     * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_QVGA = 1007;

    /**
     * Time lapse quality level corresponding to the 2160p (3840 x 2160) resolution.
     */
    public static final int QUALITY_TIME_LAPSE_2160P = 1008;

    // Start and end of timelapse quality list
    private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
    private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_2160P;

    /**
     * High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
     * <p>
     * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to
     * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just
     * higher output frame rate and bit rate. Therefore, setting these profiles with
     * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will
     * produce high speed videos rather than slow motion videos that have different capture and
     * output (playback) frame rates. To record slow motion videos, the application must set video
     * output (playback) frame rate and bit rate appropriately via
     * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate}
     * based on the slow motion factor. If the application intends to do the video recording with
     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
     * similarly according to this CamcorderProfile.
     * </p>
     *
     * @see #videoBitRate
     * @see #videoFrameRate
     * @see MediaRecorder
     * @see MediaCodec
     * @see MediaFormat
     */
    public static final int QUALITY_HIGH_SPEED_LOW = 2000;

    /**
     * High speed ( >= 100fps) quality level corresponding to the highest available resolution.
     */
    public static final int QUALITY_HIGH_SPEED_HIGH = 2001;

    /**
     * High speed ( >= 100fps) quality level corresponding to the 480p (720 x 480) resolution.
     *
     * Note that the horizontal resolution for 480p can also be other
     * values, such as 640 or 704, instead of 720.
     */
    public static final int QUALITY_HIGH_SPEED_480P = 2002;

    /**
     * High speed ( >= 100fps) quality level corresponding to the 720p (1280 x 720) resolution.
     */
    public static final int QUALITY_HIGH_SPEED_720P = 2003;

    /**
     * High speed ( >= 100fps) quality level corresponding to the 1080p (1920 x 1080 or 1920x1088)
     * resolution.
     */
    public static final int QUALITY_HIGH_SPEED_1080P = 2004;

    /**
     * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
     * resolution.
     */
    public static final int QUALITY_HIGH_SPEED_2160P = 2005;

    // Start and end of high speed quality list
    private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P;

    /**
     * Default recording duration in seconds before the session is terminated.
     * This is useful for applications like MMS has limited file size requirement.
     */
    public int duration;

    /**
     * The quality level of the camcorder profile
     */
    public int quality;

    /**
     * The file output format of the camcorder profile
     * @see android.media.MediaRecorder.OutputFormat
     */
    public int fileFormat;

    /**
     * The video encoder being used for the video track
     * @see android.media.MediaRecorder.VideoEncoder
     */
    public int videoCodec;

    /**
     * The target video output bit rate in bits per second
     * <p>
     * This is the target recorded video output bit rate if the application configures the video
     * recording via {@link MediaRecorder#setProfile} without specifying any other
     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate
     * where the video is recorded with. If the application intends to record slow motion videos
     * with the high speed quality profiles, it must set a different video bit rate that is
     * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate
     * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if
     * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps
     * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to
     * record 1/8 factor slow motion recording videos, the application must set 30fps via
     * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion
     * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in
     * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output
     * bit rate exceeds the encoder limit. If the application intends to do the video recording with
     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
     * similarly according to this CamcorderProfile.
     * </p>
     *
     * @see #videoFrameRate
     * @see MediaRecorder
     * @see MediaCodec
     * @see MediaFormat
     */
    public int videoBitRate;

    /**
     * The target video frame rate in frames per second.
     * <p>
     * This is the target recorded video output frame rate per second if the application configures
     * the video recording via {@link MediaRecorder#setProfile} without specifying any other
     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate
     * where the video is recorded and played back with. If the application intends to create slow
     * motion use case with the high speed quality profiles, it must set a different video frame
     * rate that is corresponding to the desired output (playback) frame rate via
     * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P}
     * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application
     * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via
     * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos
     * with normal speed playback frame rate (240fps for above example). If the application intends
     * to do the video recording with {@link MediaCodec} encoder, it must set each individual field
     * of {@link MediaFormat} similarly according to this CamcorderProfile.
     * </p>
     *
     * @see #videoBitRate
     * @see MediaRecorder
     * @see MediaCodec
     * @see MediaFormat
     */
    public int videoFrameRate;

    /**
     * The target video frame width in pixels
     */
    public int videoFrameWidth;

    /**
     * The target video frame height in pixels
     */
    public int videoFrameHeight;

    /**
     * The audio encoder being used for the audio track.
     * @see android.media.MediaRecorder.AudioEncoder
     */
    public int audioCodec;

    /**
     * The target audio output bit rate in bits per second
     */
    public int audioBitRate;

    /**
     * The audio sampling rate used for the audio track
     */
    public int audioSampleRate;

    /**
     * The number of audio channels used for the audio track
     */
    public int audioChannels;

    /**
     * Returns the camcorder profile for the first back-facing camera on the
     * device at the given quality level. If the device has no back-facing
     * camera, this returns null.
     * @param quality the target quality level for the camcorder profile
     * @see #get(int, int)
     */
    public static CamcorderProfile get(int quality) {
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                return get(i, quality);
            }
        }
        return null;
    }

    /**
     * Returns the camcorder profile for the given camera at the given
     * quality level.
     *
     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
     * other levels may or may not be supported. The supported levels can be checked using
     * {@link #hasProfile(int, int)}.
     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
     * the highest quality available.
     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
     * 2160p.
     *
     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
     * qcif, cif, 480p, 720p, 1080p, or 2160p.
     *
     * For high speed quality levels, they may or may not be supported. If a subset of the levels
     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
     * supported and have to match one of 480p, 720p, or 1080p.
     *
     * A camcorder recording session with higher quality level usually has higher output
     * bit rate, better video and/or audio recording quality, larger video frame
     * resolution and higher audio sampling rate, etc, than those with lower quality
     * level.
     *
     * @param cameraId the id for the camera
     * @param quality the target quality level for the camcorder profile.
     * @see #QUALITY_LOW
     * @see #QUALITY_HIGH
     * @see #QUALITY_QCIF
     * @see #QUALITY_CIF
     * @see #QUALITY_480P
     * @see #QUALITY_720P
     * @see #QUALITY_1080P
     * @see #QUALITY_2160P
     * @see #QUALITY_TIME_LAPSE_LOW
     * @see #QUALITY_TIME_LAPSE_HIGH
     * @see #QUALITY_TIME_LAPSE_QCIF
     * @see #QUALITY_TIME_LAPSE_CIF
     * @see #QUALITY_TIME_LAPSE_480P
     * @see #QUALITY_TIME_LAPSE_720P
     * @see #QUALITY_TIME_LAPSE_1080P
     * @see #QUALITY_TIME_LAPSE_2160P
     * @see #QUALITY_HIGH_SPEED_LOW
     * @see #QUALITY_HIGH_SPEED_HIGH
     * @see #QUALITY_HIGH_SPEED_480P
     * @see #QUALITY_HIGH_SPEED_720P
     * @see #QUALITY_HIGH_SPEED_1080P
     * @see #QUALITY_HIGH_SPEED_2160P
    */
    public static CamcorderProfile get(int cameraId, int quality) {
        if (!((quality >= QUALITY_LIST_START &&
               quality <= QUALITY_LIST_END) ||
              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
            String errMessage = "Unsupported quality level: " + quality;
            throw new IllegalArgumentException(errMessage);
        }
        return native_get_camcorder_profile(cameraId, quality);
    }

    /**
     * Returns true if camcorder profile exists for the first back-facing
     * camera at the given quality level.
     *
     * <p>
     * When using the Camera 2 API in {@code LEGACY} mode (i.e. when
     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
     * to
     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
     * a given resolution is supported in LEGACY mode, the configuration given in
     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
     * must contain the the resolution in the supported output sizes.  The recommended way to check
     * this is with
     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
     * class of the desired recording endpoint, and check that the desired resolution is contained
     * in the list returned.
     * </p>
     * @see android.hardware.camera2.CameraManager
     * @see android.hardware.camera2.CameraCharacteristics
     *
     * @param quality the target quality level for the camcorder profile
     */
    public static boolean hasProfile(int quality) {
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                return hasProfile(i, quality);
            }
        }
        return false;
    }

    /**
     * Returns true if camcorder profile exists for the given camera at
     * the given quality level.
     *
     * <p>
     * When using the Camera 2 API in LEGACY mode (i.e. when
     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
     * to
     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
     * a given resolution is supported in LEGACY mode, the configuration given in
     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
     * must contain the the resolution in the supported output sizes.  The recommended way to check
     * this is with
     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
     * class of the desired recording endpoint, and check that the desired resolution is contained
     * in the list returned.
     * </p>
     * @see android.hardware.camera2.CameraManager
     * @see android.hardware.camera2.CameraCharacteristics
     *
     * @param cameraId the id for the camera
     * @param quality the target quality level for the camcorder profile
     */
    public static boolean hasProfile(int cameraId, int quality) {
        return native_has_camcorder_profile(cameraId, quality);
    }

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

    // Private constructor called by JNI
    private CamcorderProfile(int duration,
                             int quality,
                             int fileFormat,
                             int videoCodec,
                             int videoBitRate,
                             int videoFrameRate,
                             int videoWidth,
                             int videoHeight,
                             int audioCodec,
                             int audioBitRate,
                             int audioSampleRate,
                             int audioChannels) {

        this.duration         = duration;
        this.quality          = quality;
        this.fileFormat       = fileFormat;
        this.videoCodec       = videoCodec;
        this.videoBitRate     = videoBitRate;
        this.videoFrameRate   = videoFrameRate;
        this.videoFrameWidth  = videoWidth;
        this.videoFrameHeight = videoHeight;
        this.audioCodec       = audioCodec;
        this.audioBitRate     = audioBitRate;
        this.audioSampleRate  = audioSampleRate;
        this.audioChannels    = audioChannels;
    }

    // Methods implemented by JNI
    private static native final void native_init();
    private static native final CamcorderProfile native_get_camcorder_profile(
            int cameraId, int quality);
    private static native final boolean native_has_camcorder_profile(
            int cameraId, int quality);
}
