Java tutorial
/* * 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.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Build; /** * 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 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static native final void native_init(); @UnsupportedAppUsage 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); }