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 
17 package android.media;
18 
19 import android.hardware.Camera;
20 import 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  */
43 public 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      */
get(int quality)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     */
get(int cameraId, int quality)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      */
hasProfile(int quality)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      */
hasProfile(int cameraId, int quality)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");
native_init()466         native_init();
467     }
468 
469     // Private constructor called by JNI
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)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
native_init()498     private static native final void native_init();
native_get_camcorder_profile( int cameraId, int quality)499     private static native final CamcorderProfile native_get_camcorder_profile(
500             int cameraId, int quality);
native_has_camcorder_profile( int cameraId, int quality)501     private static native final boolean native_has_camcorder_profile(
502             int cameraId, int quality);
503 }
504