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     * <p>
154     * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to
155     * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just
156     * higher output frame rate and bit rate. Therefore, setting these profiles with
157     * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will
158     * produce high speed videos rather than slow motion videos that have different capture and
159     * output (playback) frame rates. To record slow motion videos, the application must set video
160     * output (playback) frame rate and bit rate appropriately via
161     * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate}
162     * based on the slow motion factor. If the application intends to do the video recording with
163     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
164     * similarly according to this CamcorderProfile.
165     * </p>
166     *
167     * @see #videoBitRate
168     * @see #videoFrameRate
169     * @see MediaRecorder
170     * @see MediaCodec
171     * @see MediaFormat
172     */
173    public static final int QUALITY_HIGH_SPEED_LOW = 2000;
174
175    /**
176     * High speed ( >= 100fps) quality level corresponding to the highest available resolution.
177     */
178    public static final int QUALITY_HIGH_SPEED_HIGH = 2001;
179
180    /**
181     * High speed ( >= 100fps) quality level corresponding to the 480p (720 x 480) resolution.
182     *
183     * Note that the horizontal resolution for 480p can also be other
184     * values, such as 640 or 704, instead of 720.
185     */
186    public static final int QUALITY_HIGH_SPEED_480P = 2002;
187
188    /**
189     * High speed ( >= 100fps) quality level corresponding to the 720p (1280 x 720) resolution.
190     */
191    public static final int QUALITY_HIGH_SPEED_720P = 2003;
192
193    /**
194     * High speed ( >= 100fps) quality level corresponding to the 1080p (1920 x 1080 or 1920x1088)
195     * resolution.
196     */
197    public static final int QUALITY_HIGH_SPEED_1080P = 2004;
198
199    /**
200     * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
201     * resolution.
202     */
203    public static final int QUALITY_HIGH_SPEED_2160P = 2005;
204
205    // Start and end of high speed quality list
206    private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
207    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P;
208
209    /**
210     * Default recording duration in seconds before the session is terminated.
211     * This is useful for applications like MMS has limited file size requirement.
212     */
213    public int duration;
214
215    /**
216     * The quality level of the camcorder profile
217     */
218    public int quality;
219
220    /**
221     * The file output format of the camcorder profile
222     * @see android.media.MediaRecorder.OutputFormat
223     */
224    public int fileFormat;
225
226    /**
227     * The video encoder being used for the video track
228     * @see android.media.MediaRecorder.VideoEncoder
229     */
230    public int videoCodec;
231
232    /**
233     * The target video output bit rate in bits per second
234     * <p>
235     * This is the target recorded video output bit rate if the application configures the video
236     * recording via {@link MediaRecorder#setProfile} without specifying any other
237     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
238     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate
239     * where the video is recorded with. If the application intends to record slow motion videos
240     * with the high speed quality profiles, it must set a different video bit rate that is
241     * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate
242     * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if
243     * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps
244     * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to
245     * record 1/8 factor slow motion recording videos, the application must set 30fps via
246     * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion
247     * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in
248     * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output
249     * bit rate exceeds the encoder limit. If the application intends to do the video recording with
250     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
251     * similarly according to this CamcorderProfile.
252     * </p>
253     *
254     * @see #videoFrameRate
255     * @see MediaRecorder
256     * @see MediaCodec
257     * @see MediaFormat
258     */
259    public int videoBitRate;
260
261    /**
262     * The target video frame rate in frames per second.
263     * <p>
264     * This is the target recorded video output frame rate per second if the application configures
265     * the video recording via {@link MediaRecorder#setProfile} without specifying any other
266     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
267     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate
268     * where the video is recorded and played back with. If the application intends to create slow
269     * motion use case with the high speed quality profiles, it must set a different video frame
270     * rate that is corresponding to the desired output (playback) frame rate via
271     * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P}
272     * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application
273     * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via
274     * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos
275     * with normal speed playback frame rate (240fps for above example). If the application intends
276     * to do the video recording with {@link MediaCodec} encoder, it must set each individual field
277     * of {@link MediaFormat} similarly according to this CamcorderProfile.
278     * </p>
279     *
280     * @see #videoBitRate
281     * @see MediaRecorder
282     * @see MediaCodec
283     * @see MediaFormat
284     */
285    public int videoFrameRate;
286
287    /**
288     * The target video frame width in pixels
289     */
290    public int videoFrameWidth;
291
292    /**
293     * The target video frame height in pixels
294     */
295    public int videoFrameHeight;
296
297    /**
298     * The audio encoder being used for the audio track.
299     * @see android.media.MediaRecorder.AudioEncoder
300     */
301    public int audioCodec;
302
303    /**
304     * The target audio output bit rate in bits per second
305     */
306    public int audioBitRate;
307
308    /**
309     * The audio sampling rate used for the audio track
310     */
311    public int audioSampleRate;
312
313    /**
314     * The number of audio channels used for the audio track
315     */
316    public int audioChannels;
317
318    /**
319     * Returns the camcorder profile for the first back-facing camera on the
320     * device at the given quality level. If the device has no back-facing
321     * camera, this returns null.
322     * @param quality the target quality level for the camcorder profile
323     * @see #get(int, int)
324     */
325    public static CamcorderProfile get(int quality) {
326        int numberOfCameras = Camera.getNumberOfCameras();
327        CameraInfo cameraInfo = new CameraInfo();
328        for (int i = 0; i < numberOfCameras; i++) {
329            Camera.getCameraInfo(i, cameraInfo);
330            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
331                return get(i, quality);
332            }
333        }
334        return null;
335    }
336
337    /**
338     * Returns the camcorder profile for the given camera at the given
339     * quality level.
340     *
341     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
342     * other levels may or may not be supported. The supported levels can be checked using
343     * {@link #hasProfile(int, int)}.
344     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
345     * the highest quality available.
346     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
347     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
348     * 2160p.
349     *
350     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
351     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
352     * qcif, cif, 480p, 720p, 1080p, or 2160p.
353     *
354     * For high speed quality levels, they may or may not be supported. If a subset of the levels
355     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
356     * supported and have to match one of 480p, 720p, or 1080p.
357     *
358     * A camcorder recording session with higher quality level usually has higher output
359     * bit rate, better video and/or audio recording quality, larger video frame
360     * resolution and higher audio sampling rate, etc, than those with lower quality
361     * level.
362     *
363     * @param cameraId the id for the camera
364     * @param quality the target quality level for the camcorder profile.
365     * @see #QUALITY_LOW
366     * @see #QUALITY_HIGH
367     * @see #QUALITY_QCIF
368     * @see #QUALITY_CIF
369     * @see #QUALITY_480P
370     * @see #QUALITY_720P
371     * @see #QUALITY_1080P
372     * @see #QUALITY_2160P
373     * @see #QUALITY_TIME_LAPSE_LOW
374     * @see #QUALITY_TIME_LAPSE_HIGH
375     * @see #QUALITY_TIME_LAPSE_QCIF
376     * @see #QUALITY_TIME_LAPSE_CIF
377     * @see #QUALITY_TIME_LAPSE_480P
378     * @see #QUALITY_TIME_LAPSE_720P
379     * @see #QUALITY_TIME_LAPSE_1080P
380     * @see #QUALITY_TIME_LAPSE_2160P
381     * @see #QUALITY_HIGH_SPEED_LOW
382     * @see #QUALITY_HIGH_SPEED_HIGH
383     * @see #QUALITY_HIGH_SPEED_480P
384     * @see #QUALITY_HIGH_SPEED_720P
385     * @see #QUALITY_HIGH_SPEED_1080P
386     * @see #QUALITY_HIGH_SPEED_2160P
387    */
388    public static CamcorderProfile get(int cameraId, int quality) {
389        if (!((quality >= QUALITY_LIST_START &&
390               quality <= QUALITY_LIST_END) ||
391              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
392               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
393               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
394               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
395            String errMessage = "Unsupported quality level: " + quality;
396            throw new IllegalArgumentException(errMessage);
397        }
398        return native_get_camcorder_profile(cameraId, quality);
399    }
400
401    /**
402     * Returns true if camcorder profile exists for the first back-facing
403     * camera at the given quality level.
404     *
405     * <p>
406     * When using the Camera 2 API in {@code LEGACY} mode (i.e. when
407     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
408     * to
409     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
410     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
411     * a given resolution is supported in LEGACY mode, the configuration given in
412     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
413     * must contain the the resolution in the supported output sizes.  The recommended way to check
414     * this is with
415     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
416     * class of the desired recording endpoint, and check that the desired resolution is contained
417     * in the list returned.
418     * </p>
419     * @see android.hardware.camera2.CameraManager
420     * @see android.hardware.camera2.CameraCharacteristics
421     *
422     * @param quality the target quality level for the camcorder profile
423     */
424    public static boolean hasProfile(int quality) {
425        int numberOfCameras = Camera.getNumberOfCameras();
426        CameraInfo cameraInfo = new CameraInfo();
427        for (int i = 0; i < numberOfCameras; i++) {
428            Camera.getCameraInfo(i, cameraInfo);
429            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
430                return hasProfile(i, quality);
431            }
432        }
433        return false;
434    }
435
436    /**
437     * Returns true if camcorder profile exists for the given camera at
438     * the given quality level.
439     *
440     * <p>
441     * When using the Camera 2 API in LEGACY mode (i.e. when
442     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
443     * to
444     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
445     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
446     * a given resolution is supported in LEGACY mode, the configuration given in
447     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
448     * must contain the the resolution in the supported output sizes.  The recommended way to check
449     * this is with
450     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
451     * class of the desired recording endpoint, and check that the desired resolution is contained
452     * in the list returned.
453     * </p>
454     * @see android.hardware.camera2.CameraManager
455     * @see android.hardware.camera2.CameraCharacteristics
456     *
457     * @param cameraId the id for the camera
458     * @param quality the target quality level for the camcorder profile
459     */
460    public static boolean hasProfile(int cameraId, int quality) {
461        return native_has_camcorder_profile(cameraId, quality);
462    }
463
464    static {
465        System.loadLibrary("media_jni");
466        native_init();
467    }
468
469    // Private constructor called by JNI
470    private CamcorderProfile(int duration,
471                             int quality,
472                             int fileFormat,
473                             int videoCodec,
474                             int videoBitRate,
475                             int videoFrameRate,
476                             int videoWidth,
477                             int videoHeight,
478                             int audioCodec,
479                             int audioBitRate,
480                             int audioSampleRate,
481                             int audioChannels) {
482
483        this.duration         = duration;
484        this.quality          = quality;
485        this.fileFormat       = fileFormat;
486        this.videoCodec       = videoCodec;
487        this.videoBitRate     = videoBitRate;
488        this.videoFrameRate   = videoFrameRate;
489        this.videoFrameWidth  = videoWidth;
490        this.videoFrameHeight = videoHeight;
491        this.audioCodec       = audioCodec;
492        this.audioBitRate     = audioBitRate;
493        this.audioSampleRate  = audioSampleRate;
494        this.audioChannels    = audioChannels;
495    }
496
497    // Methods implemented by JNI
498    private static native final void native_init();
499    private static native final CamcorderProfile native_get_camcorder_profile(
500            int cameraId, int quality);
501    private static native final boolean native_has_camcorder_profile(
502            int cameraId, int quality);
503}
504