1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.hardware.Camera;
20import android.hardware.Camera.CameraInfo;
21
22/**
23 * Retrieves the
24 * predefined camcorder profile settings for camcorder applications.
25 * These settings are read-only.
26 *
27 * <p>The compressed output from a recording session with a given
28 * CamcorderProfile contains two tracks: one for audio and one for video.
29 *
30 * <p>Each profile specifies the following set of parameters:
31 * <ul>
32 * <li> The file output format
33 * <li> Video codec format
34 * <li> Video bit rate in bits per second
35 * <li> Video frame rate in frames per second
36 * <li> Video frame width and height,
37 * <li> Audio codec format
38 * <li> Audio bit rate in bits per second,
39 * <li> Audio sample rate
40 * <li> Number of audio channels for recording.
41 * </ul>
42 */
43public class CamcorderProfile
44{
45    // Do not change these values/ordinals without updating their counterpart
46    // in include/media/MediaProfiles.h!
47
48    /**
49     * Quality level corresponding to the lowest available resolution.
50     */
51    public static final int QUALITY_LOW  = 0;
52
53    /**
54     * Quality level corresponding to the highest available resolution.
55     */
56    public static final int QUALITY_HIGH = 1;
57
58    /**
59     * Quality level corresponding to the qcif (176 x 144) resolution.
60     */
61    public static final int QUALITY_QCIF = 2;
62
63    /**
64     * Quality level corresponding to the cif (352 x 288) resolution.
65     */
66    public static final int QUALITY_CIF = 3;
67
68    /**
69     * Quality level corresponding to the 480p (720 x 480) resolution.
70     * Note that the horizontal resolution for 480p can also be other
71     * values, such as 640 or 704, instead of 720.
72     */
73    public static final int QUALITY_480P = 4;
74
75    /**
76     * Quality level corresponding to the 720p (1280 x 720) resolution.
77     */
78    public static final int QUALITY_720P = 5;
79
80    /**
81     * Quality level corresponding to the 1080p (1920 x 1080) resolution.
82     * Note that the vertical resolution for 1080p can also be 1088,
83     * instead of 1080 (used by some vendors to avoid cropping during
84     * video playback).
85     */
86    public static final int QUALITY_1080P = 6;
87
88    /**
89     * Quality level corresponding to the QVGA (320x240) resolution.
90     */
91    public static final int QUALITY_QVGA = 7;
92
93    /**
94     * Quality level corresponding to the 2160p (3840x2160) resolution.
95     */
96    public static final int QUALITY_2160P = 8;
97
98    // Start and end of quality list
99    private static final int QUALITY_LIST_START = QUALITY_LOW;
100    private static final int QUALITY_LIST_END = QUALITY_2160P;
101
102    /**
103     * Time lapse quality level corresponding to the lowest available resolution.
104     */
105    public static final int QUALITY_TIME_LAPSE_LOW  = 1000;
106
107    /**
108     * Time lapse quality level corresponding to the highest available resolution.
109     */
110    public static final int QUALITY_TIME_LAPSE_HIGH = 1001;
111
112    /**
113     * Time lapse quality level corresponding to the qcif (176 x 144) resolution.
114     */
115    public static final int QUALITY_TIME_LAPSE_QCIF = 1002;
116
117    /**
118     * Time lapse quality level corresponding to the cif (352 x 288) resolution.
119     */
120    public static final int QUALITY_TIME_LAPSE_CIF = 1003;
121
122    /**
123     * Time lapse quality level corresponding to the 480p (720 x 480) resolution.
124     */
125    public static final int QUALITY_TIME_LAPSE_480P = 1004;
126
127    /**
128     * Time lapse quality level corresponding to the 720p (1280 x 720) resolution.
129     */
130    public static final int QUALITY_TIME_LAPSE_720P = 1005;
131
132    /**
133     * Time lapse quality level corresponding to the 1080p (1920 x 1088) resolution.
134     */
135    public static final int QUALITY_TIME_LAPSE_1080P = 1006;
136
137    /**
138     * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
139     */
140    public static final int QUALITY_TIME_LAPSE_QVGA = 1007;
141
142    /**
143     * Time lapse quality level corresponding to the 2160p (3840 x 2160) resolution.
144     */
145    public static final int QUALITY_TIME_LAPSE_2160P = 1008;
146
147    // Start and end of timelapse quality list
148    private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
149    private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_2160P;
150
151    /**
152     * High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
153     */
154    public static final int QUALITY_HIGH_SPEED_LOW = 2000;
155
156    /**
157     * High speed ( >= 100fps) quality level corresponding to the highest available resolution.
158     */
159    public static final int QUALITY_HIGH_SPEED_HIGH = 2001;
160
161    /**
162     * High speed ( >= 100fps) quality level corresponding to the 480p (720 x 480) resolution.
163     *
164     * Note that the horizontal resolution for 480p can also be other
165     * values, such as 640 or 704, instead of 720.
166     */
167    public static final int QUALITY_HIGH_SPEED_480P = 2002;
168
169    /**
170     * High speed ( >= 100fps) quality level corresponding to the 720p (1280 x 720) resolution.
171     */
172    public static final int QUALITY_HIGH_SPEED_720P = 2003;
173
174    /**
175     * High speed ( >= 100fps) quality level corresponding to the 1080p (1920 x 1080 or 1920x1088)
176     * resolution.
177     */
178    public static final int QUALITY_HIGH_SPEED_1080P = 2004;
179
180    /**
181     * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
182     * resolution.
183     */
184    public static final int QUALITY_HIGH_SPEED_2160P = 2005;
185
186    // Start and end of high speed quality list
187    private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
188    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P;
189
190    /**
191     * Default recording duration in seconds before the session is terminated.
192     * This is useful for applications like MMS has limited file size requirement.
193     */
194    public int duration;
195
196    /**
197     * The quality level of the camcorder profile
198     */
199    public int quality;
200
201    /**
202     * The file output format of the camcorder profile
203     * @see android.media.MediaRecorder.OutputFormat
204     */
205    public int fileFormat;
206
207    /**
208     * The video encoder being used for the video track
209     * @see android.media.MediaRecorder.VideoEncoder
210     */
211    public int videoCodec;
212
213    /**
214     * The target video output bit rate in bits per second
215     */
216    public int videoBitRate;
217
218    /**
219     * The target video frame rate in frames per second
220     */
221    public int videoFrameRate;
222
223    /**
224     * The target video frame width in pixels
225     */
226    public int videoFrameWidth;
227
228    /**
229     * The target video frame height in pixels
230     */
231    public int videoFrameHeight;
232
233    /**
234     * The audio encoder being used for the audio track.
235     * @see android.media.MediaRecorder.AudioEncoder
236     */
237    public int audioCodec;
238
239    /**
240     * The target audio output bit rate in bits per second
241     */
242    public int audioBitRate;
243
244    /**
245     * The audio sampling rate used for the audio track
246     */
247    public int audioSampleRate;
248
249    /**
250     * The number of audio channels used for the audio track
251     */
252    public int audioChannels;
253
254    /**
255     * Returns the camcorder profile for the first back-facing camera on the
256     * device at the given quality level. If the device has no back-facing
257     * camera, this returns null.
258     * @param quality the target quality level for the camcorder profile
259     * @see #get(int, int)
260     */
261    public static CamcorderProfile get(int quality) {
262        int numberOfCameras = Camera.getNumberOfCameras();
263        CameraInfo cameraInfo = new CameraInfo();
264        for (int i = 0; i < numberOfCameras; i++) {
265            Camera.getCameraInfo(i, cameraInfo);
266            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
267                return get(i, quality);
268            }
269        }
270        return null;
271    }
272
273    /**
274     * Returns the camcorder profile for the given camera at the given
275     * quality level.
276     *
277     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
278     * other levels may or may not be supported. The supported levels can be checked using
279     * {@link #hasProfile(int, int)}.
280     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
281     * the highest quality available.
282     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
283     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
284     * 2160p.
285     *
286     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
287     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
288     * qcif, cif, 480p, 720p, 1080p, or 2160p.
289     *
290     * For high speed quality levels, they may or may not be supported. If a subset of the levels
291     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
292     * supported and have to match one of 480p, 720p, or 1080p.
293     *
294     * A camcorder recording session with higher quality level usually has higher output
295     * bit rate, better video and/or audio recording quality, larger video frame
296     * resolution and higher audio sampling rate, etc, than those with lower quality
297     * level.
298     *
299     * @param cameraId the id for the camera
300     * @param quality the target quality level for the camcorder profile.
301     * @see #QUALITY_LOW
302     * @see #QUALITY_HIGH
303     * @see #QUALITY_QCIF
304     * @see #QUALITY_CIF
305     * @see #QUALITY_480P
306     * @see #QUALITY_720P
307     * @see #QUALITY_1080P
308     * @see #QUALITY_2160P
309     * @see #QUALITY_TIME_LAPSE_LOW
310     * @see #QUALITY_TIME_LAPSE_HIGH
311     * @see #QUALITY_TIME_LAPSE_QCIF
312     * @see #QUALITY_TIME_LAPSE_CIF
313     * @see #QUALITY_TIME_LAPSE_480P
314     * @see #QUALITY_TIME_LAPSE_720P
315     * @see #QUALITY_TIME_LAPSE_1080P
316     * @see #QUALITY_TIME_LAPSE_2160P
317     * @see #QUALITY_HIGH_SPEED_LOW
318     * @see #QUALITY_HIGH_SPEED_HIGH
319     * @see #QUALITY_HIGH_SPEED_480P
320     * @see #QUALITY_HIGH_SPEED_720P
321     * @see #QUALITY_HIGH_SPEED_1080P
322     * @see #QUALITY_HIGH_SPEED_2160P
323    */
324    public static CamcorderProfile get(int cameraId, int quality) {
325        if (!((quality >= QUALITY_LIST_START &&
326               quality <= QUALITY_LIST_END) ||
327              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
328               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
329               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
330               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
331            String errMessage = "Unsupported quality level: " + quality;
332            throw new IllegalArgumentException(errMessage);
333        }
334        return native_get_camcorder_profile(cameraId, quality);
335    }
336
337    /**
338     * Returns true if camcorder profile exists for the first back-facing
339     * camera at the given quality level.
340     *
341     * <p>
342     * When using the Camera 2 API in {@code LEGACY} mode (i.e. when
343     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
344     * to
345     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
346     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
347     * a given resolution is supported in LEGACY mode, the configuration given in
348     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
349     * must contain the the resolution in the supported output sizes.  The recommended way to check
350     * this is with
351     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
352     * class of the desired recording endpoint, and check that the desired resolution is contained
353     * in the list returned.
354     * </p>
355     * @see android.hardware.camera2.CameraManager
356     * @see android.hardware.camera2.CameraCharacteristics
357     *
358     * @param quality the target quality level for the camcorder profile
359     */
360    public static boolean hasProfile(int quality) {
361        int numberOfCameras = Camera.getNumberOfCameras();
362        CameraInfo cameraInfo = new CameraInfo();
363        for (int i = 0; i < numberOfCameras; i++) {
364            Camera.getCameraInfo(i, cameraInfo);
365            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
366                return hasProfile(i, quality);
367            }
368        }
369        return false;
370    }
371
372    /**
373     * Returns true if camcorder profile exists for the given camera at
374     * the given quality level.
375     *
376     * <p>
377     * When using the Camera 2 API in LEGACY mode (i.e. when
378     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
379     * to
380     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
381     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
382     * a given resolution is supported in LEGACY mode, the configuration given in
383     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
384     * must contain the the resolution in the supported output sizes.  The recommended way to check
385     * this is with
386     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
387     * class of the desired recording endpoint, and check that the desired resolution is contained
388     * in the list returned.
389     * </p>
390     * @see android.hardware.camera2.CameraManager
391     * @see android.hardware.camera2.CameraCharacteristics
392     *
393     * @param cameraId the id for the camera
394     * @param quality the target quality level for the camcorder profile
395     */
396    public static boolean hasProfile(int cameraId, int quality) {
397        return native_has_camcorder_profile(cameraId, quality);
398    }
399
400    static {
401        System.loadLibrary("media_jni");
402        native_init();
403    }
404
405    // Private constructor called by JNI
406    private CamcorderProfile(int duration,
407                             int quality,
408                             int fileFormat,
409                             int videoCodec,
410                             int videoBitRate,
411                             int videoFrameRate,
412                             int videoWidth,
413                             int videoHeight,
414                             int audioCodec,
415                             int audioBitRate,
416                             int audioSampleRate,
417                             int audioChannels) {
418
419        this.duration         = duration;
420        this.quality          = quality;
421        this.fileFormat       = fileFormat;
422        this.videoCodec       = videoCodec;
423        this.videoBitRate     = videoBitRate;
424        this.videoFrameRate   = videoFrameRate;
425        this.videoFrameWidth  = videoWidth;
426        this.videoFrameHeight = videoHeight;
427        this.audioCodec       = audioCodec;
428        this.audioBitRate     = audioBitRate;
429        this.audioSampleRate  = audioSampleRate;
430        this.audioChannels    = audioChannels;
431    }
432
433    // Methods implemented by JNI
434    private static native final void native_init();
435    private static native final CamcorderProfile native_get_camcorder_profile(
436            int cameraId, int quality);
437    private static native final boolean native_has_camcorder_profile(
438            int cameraId, int quality);
439}
440