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.compat.annotation.UnsupportedAppUsage;
20 import android.hardware.Camera;
21 import android.hardware.Camera.CameraInfo;
22 import android.os.Build;
23 
24 /**
25  * Retrieves the
26  * predefined camcorder profile settings for camcorder applications.
27  * These settings are read-only.
28  *
29  * <p>The compressed output from a recording session with a given
30  * CamcorderProfile contains two tracks: one for audio and one for video.
31  *
32  * <p>Each profile specifies the following set of parameters:
33  * <ul>
34  * <li> The file output format
35  * <li> Video codec format
36  * <li> Video bit rate in bits per second
37  * <li> Video frame rate in frames per second
38  * <li> Video frame width and height,
39  * <li> Audio codec format
40  * <li> Audio bit rate in bits per second,
41  * <li> Audio sample rate
42  * <li> Number of audio channels for recording.
43  * </ul>
44  */
45 public class CamcorderProfile
46 {
47     // Do not change these values/ordinals without updating their counterpart
48     // in include/media/MediaProfiles.h!
49 
50     /**
51      * Quality level corresponding to the lowest available resolution.
52      */
53     public static final int QUALITY_LOW  = 0;
54 
55     /**
56      * Quality level corresponding to the highest available resolution.
57      */
58     public static final int QUALITY_HIGH = 1;
59 
60     /**
61      * Quality level corresponding to the qcif (176 x 144) resolution.
62      */
63     public static final int QUALITY_QCIF = 2;
64 
65     /**
66      * Quality level corresponding to the cif (352 x 288) resolution.
67      */
68     public static final int QUALITY_CIF = 3;
69 
70     /**
71      * Quality level corresponding to the 480p (720 x 480) resolution.
72      * Note that the horizontal resolution for 480p can also be other
73      * values, such as 640 or 704, instead of 720.
74      */
75     public static final int QUALITY_480P = 4;
76 
77     /**
78      * Quality level corresponding to the 720p (1280 x 720) resolution.
79      */
80     public static final int QUALITY_720P = 5;
81 
82     /**
83      * Quality level corresponding to the 1080p (1920 x 1080) resolution.
84      * Note that the vertical resolution for 1080p can also be 1088,
85      * instead of 1080 (used by some vendors to avoid cropping during
86      * video playback).
87      */
88     public static final int QUALITY_1080P = 6;
89 
90     /**
91      * Quality level corresponding to the QVGA (320x240) resolution.
92      */
93     public static final int QUALITY_QVGA = 7;
94 
95     /**
96      * Quality level corresponding to the 2160p (3840x2160) resolution.
97      */
98     public static final int QUALITY_2160P = 8;
99 
100     /**
101      * Quality level corresponding to the VGA (640 x 480) resolution.
102      * @hide
103      */
104     public static final int QUALITY_VGA = 9;
105 
106     /**
107      * Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
108      * @hide
109      */
110     public static final int QUALITY_4KDCI = 10;
111 
112     /**
113      * Quality level corresponding to QHD (2560 x 1440) resolution
114      * @hide
115      */
116     public static final int QUALITY_QHD = 11;
117 
118     /**
119      * Quality level corresponding to 2K (2048 x 1080) resolution
120      * @hide
121      */
122     public static final int QUALITY_2K = 12;
123 
124     // Start and end of quality list
125     private static final int QUALITY_LIST_START = QUALITY_LOW;
126     private static final int QUALITY_LIST_END = QUALITY_2K;
127 
128     /**
129      * Time lapse quality level corresponding to the lowest available resolution.
130      */
131     public static final int QUALITY_TIME_LAPSE_LOW  = 1000;
132 
133     /**
134      * Time lapse quality level corresponding to the highest available resolution.
135      */
136     public static final int QUALITY_TIME_LAPSE_HIGH = 1001;
137 
138     /**
139      * Time lapse quality level corresponding to the qcif (176 x 144) resolution.
140      */
141     public static final int QUALITY_TIME_LAPSE_QCIF = 1002;
142 
143     /**
144      * Time lapse quality level corresponding to the cif (352 x 288) resolution.
145      */
146     public static final int QUALITY_TIME_LAPSE_CIF = 1003;
147 
148     /**
149      * Time lapse quality level corresponding to the 480p (720 x 480) resolution.
150      */
151     public static final int QUALITY_TIME_LAPSE_480P = 1004;
152 
153     /**
154      * Time lapse quality level corresponding to the 720p (1280 x 720) resolution.
155      */
156     public static final int QUALITY_TIME_LAPSE_720P = 1005;
157 
158     /**
159      * Time lapse quality level corresponding to the 1080p (1920 x 1088) resolution.
160      */
161     public static final int QUALITY_TIME_LAPSE_1080P = 1006;
162 
163     /**
164      * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
165      */
166     public static final int QUALITY_TIME_LAPSE_QVGA = 1007;
167 
168     /**
169      * Time lapse quality level corresponding to the 2160p (3840 x 2160) resolution.
170      */
171     public static final int QUALITY_TIME_LAPSE_2160P = 1008;
172 
173     /**
174      * Time lapse quality level corresponding to the VGA (640 x 480) resolution.
175      * @hide
176      */
177     public static final int QUALITY_TIME_LAPSE_VGA = 1009;
178 
179     /**
180      * Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
181      * @hide
182      */
183     public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
184 
185     /**
186      * Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
187      * @hide
188      */
189     public static final int QUALITY_TIME_LAPSE_QHD = 1011;
190 
191     /**
192      * Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
193      * @hide
194      */
195     public static final int QUALITY_TIME_LAPSE_2K = 1012;
196 
197 
198     // Start and end of timelapse quality list
199     private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
200     private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_2K;
201 
202     /**
203      * High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
204      * <p>
205      * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to
206      * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just
207      * higher output frame rate and bit rate. Therefore, setting these profiles with
208      * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will
209      * produce high speed videos rather than slow motion videos that have different capture and
210      * output (playback) frame rates. To record slow motion videos, the application must set video
211      * output (playback) frame rate and bit rate appropriately via
212      * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate}
213      * based on the slow motion factor. If the application intends to do the video recording with
214      * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
215      * similarly according to this CamcorderProfile.
216      * </p>
217      *
218      * @see #videoBitRate
219      * @see #videoFrameRate
220      * @see MediaRecorder
221      * @see MediaCodec
222      * @see MediaFormat
223      */
224     public static final int QUALITY_HIGH_SPEED_LOW = 2000;
225 
226     /**
227      * High speed ( >= 100fps) quality level corresponding to the highest available resolution.
228      */
229     public static final int QUALITY_HIGH_SPEED_HIGH = 2001;
230 
231     /**
232      * High speed ( >= 100fps) quality level corresponding to the 480p (720 x 480) resolution.
233      *
234      * Note that the horizontal resolution for 480p can also be other
235      * values, such as 640 or 704, instead of 720.
236      */
237     public static final int QUALITY_HIGH_SPEED_480P = 2002;
238 
239     /**
240      * High speed ( >= 100fps) quality level corresponding to the 720p (1280 x 720) resolution.
241      */
242     public static final int QUALITY_HIGH_SPEED_720P = 2003;
243 
244     /**
245      * High speed ( >= 100fps) quality level corresponding to the 1080p (1920 x 1080 or 1920x1088)
246      * resolution.
247      */
248     public static final int QUALITY_HIGH_SPEED_1080P = 2004;
249 
250     /**
251      * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
252      * resolution.
253      */
254     public static final int QUALITY_HIGH_SPEED_2160P = 2005;
255 
256     /**
257      * High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
258      * @hide
259      */
260     public static final int QUALITY_HIGH_SPEED_CIF = 2006;
261 
262     /**
263      * High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
264      * @hide
265      */
266     public static final int QUALITY_HIGH_SPEED_VGA = 2007;
267 
268     /**
269      * High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
270      * @hide
271      */
272     public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
273 
274     // Start and end of high speed quality list
275     private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
276     private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_4KDCI;
277 
278     /**
279      * Default recording duration in seconds before the session is terminated.
280      * This is useful for applications like MMS has limited file size requirement.
281      */
282     public int duration;
283 
284     /**
285      * The quality level of the camcorder profile
286      */
287     public int quality;
288 
289     /**
290      * The file output format of the camcorder profile
291      * @see android.media.MediaRecorder.OutputFormat
292      */
293     public int fileFormat;
294 
295     /**
296      * The video encoder being used for the video track
297      * @see android.media.MediaRecorder.VideoEncoder
298      */
299     public int videoCodec;
300 
301     /**
302      * The target video output bit rate in bits per second
303      * <p>
304      * This is the target recorded video output bit rate if the application configures the video
305      * recording via {@link MediaRecorder#setProfile} without specifying any other
306      * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
307      * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate
308      * where the video is recorded with. If the application intends to record slow motion videos
309      * with the high speed quality profiles, it must set a different video bit rate that is
310      * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate
311      * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if
312      * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps
313      * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to
314      * record 1/8 factor slow motion recording videos, the application must set 30fps via
315      * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion
316      * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in
317      * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output
318      * bit rate exceeds the encoder limit. If the application intends to do the video recording with
319      * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
320      * similarly according to this CamcorderProfile.
321      * </p>
322      *
323      * @see #videoFrameRate
324      * @see MediaRecorder
325      * @see MediaCodec
326      * @see MediaFormat
327      */
328     public int videoBitRate;
329 
330     /**
331      * The target video frame rate in frames per second.
332      * <p>
333      * This is the target recorded video output frame rate per second if the application configures
334      * the video recording via {@link MediaRecorder#setProfile} without specifying any other
335      * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
336      * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate
337      * where the video is recorded and played back with. If the application intends to create slow
338      * motion use case with the high speed quality profiles, it must set a different video frame
339      * rate that is corresponding to the desired output (playback) frame rate via
340      * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P}
341      * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application
342      * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via
343      * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos
344      * with normal speed playback frame rate (240fps for above example). If the application intends
345      * to do the video recording with {@link MediaCodec} encoder, it must set each individual field
346      * of {@link MediaFormat} similarly according to this CamcorderProfile.
347      * </p>
348      *
349      * @see #videoBitRate
350      * @see MediaRecorder
351      * @see MediaCodec
352      * @see MediaFormat
353      */
354     public int videoFrameRate;
355 
356     /**
357      * The target video frame width in pixels
358      */
359     public int videoFrameWidth;
360 
361     /**
362      * The target video frame height in pixels
363      */
364     public int videoFrameHeight;
365 
366     /**
367      * The audio encoder being used for the audio track.
368      * @see android.media.MediaRecorder.AudioEncoder
369      */
370     public int audioCodec;
371 
372     /**
373      * The target audio output bit rate in bits per second
374      */
375     public int audioBitRate;
376 
377     /**
378      * The audio sampling rate used for the audio track
379      */
380     public int audioSampleRate;
381 
382     /**
383      * The number of audio channels used for the audio track
384      */
385     public int audioChannels;
386 
387     /**
388      * Returns the camcorder profile for the first back-facing camera on the
389      * device at the given quality level. If the device has no back-facing
390      * camera, this returns null.
391      * @param quality the target quality level for the camcorder profile
392      * @see #get(int, int)
393      */
get(int quality)394     public static CamcorderProfile get(int quality) {
395         int numberOfCameras = Camera.getNumberOfCameras();
396         CameraInfo cameraInfo = new CameraInfo();
397         for (int i = 0; i < numberOfCameras; i++) {
398             Camera.getCameraInfo(i, cameraInfo);
399             if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
400                 return get(i, quality);
401             }
402         }
403         return null;
404     }
405 
406     /**
407      * Returns the camcorder profile for the given camera at the given
408      * quality level.
409      *
410      * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
411      * other levels may or may not be supported. The supported levels can be checked using
412      * {@link #hasProfile(int, int)}.
413      * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
414      * the highest quality available.
415      * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
416      * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
417      * 2160p.
418      *
419      * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
420      * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
421      * qcif, cif, 480p, 720p, 1080p, or 2160p.
422      *
423      * For high speed quality levels, they may or may not be supported. If a subset of the levels
424      * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
425      * supported and have to match one of 480p, 720p, or 1080p.
426      *
427      * A camcorder recording session with higher quality level usually has higher output
428      * bit rate, better video and/or audio recording quality, larger video frame
429      * resolution and higher audio sampling rate, etc, than those with lower quality
430      * level.
431      *
432      * @param cameraId the id for the camera
433      * @param quality the target quality level for the camcorder profile.
434      * @see #QUALITY_LOW
435      * @see #QUALITY_HIGH
436      * @see #QUALITY_QCIF
437      * @see #QUALITY_CIF
438      * @see #QUALITY_480P
439      * @see #QUALITY_720P
440      * @see #QUALITY_1080P
441      * @see #QUALITY_2160P
442      * @see #QUALITY_TIME_LAPSE_LOW
443      * @see #QUALITY_TIME_LAPSE_HIGH
444      * @see #QUALITY_TIME_LAPSE_QCIF
445      * @see #QUALITY_TIME_LAPSE_CIF
446      * @see #QUALITY_TIME_LAPSE_480P
447      * @see #QUALITY_TIME_LAPSE_720P
448      * @see #QUALITY_TIME_LAPSE_1080P
449      * @see #QUALITY_TIME_LAPSE_2160P
450      * @see #QUALITY_HIGH_SPEED_LOW
451      * @see #QUALITY_HIGH_SPEED_HIGH
452      * @see #QUALITY_HIGH_SPEED_480P
453      * @see #QUALITY_HIGH_SPEED_720P
454      * @see #QUALITY_HIGH_SPEED_1080P
455      * @see #QUALITY_HIGH_SPEED_2160P
456     */
get(int cameraId, int quality)457     public static CamcorderProfile get(int cameraId, int quality) {
458         if (!((quality >= QUALITY_LIST_START &&
459                quality <= QUALITY_LIST_END) ||
460               (quality >= QUALITY_TIME_LAPSE_LIST_START &&
461                quality <= QUALITY_TIME_LAPSE_LIST_END) ||
462                (quality >= QUALITY_HIGH_SPEED_LIST_START &&
463                quality <= QUALITY_HIGH_SPEED_LIST_END))) {
464             String errMessage = "Unsupported quality level: " + quality;
465             throw new IllegalArgumentException(errMessage);
466         }
467         return native_get_camcorder_profile(cameraId, quality);
468     }
469 
470     /**
471      * Returns true if camcorder profile exists for the first back-facing
472      * camera at the given quality level.
473      *
474      * <p>
475      * When using the Camera 2 API in {@code LEGACY} mode (i.e. when
476      * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
477      * to
478      * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
479      * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
480      * a given resolution is supported in LEGACY mode, the configuration given in
481      * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
482      * must contain the the resolution in the supported output sizes.  The recommended way to check
483      * this is with
484      * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
485      * class of the desired recording endpoint, and check that the desired resolution is contained
486      * in the list returned.
487      * </p>
488      * @see android.hardware.camera2.CameraManager
489      * @see android.hardware.camera2.CameraCharacteristics
490      *
491      * @param quality the target quality level for the camcorder profile
492      */
hasProfile(int quality)493     public static boolean hasProfile(int quality) {
494         int numberOfCameras = Camera.getNumberOfCameras();
495         CameraInfo cameraInfo = new CameraInfo();
496         for (int i = 0; i < numberOfCameras; i++) {
497             Camera.getCameraInfo(i, cameraInfo);
498             if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
499                 return hasProfile(i, quality);
500             }
501         }
502         return false;
503     }
504 
505     /**
506      * Returns true if camcorder profile exists for the given camera at
507      * the given quality level.
508      *
509      * <p>
510      * When using the Camera 2 API in LEGACY mode (i.e. when
511      * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
512      * to
513      * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
514      * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
515      * a given resolution is supported in LEGACY mode, the configuration given in
516      * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
517      * must contain the the resolution in the supported output sizes.  The recommended way to check
518      * this is with
519      * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
520      * class of the desired recording endpoint, and check that the desired resolution is contained
521      * in the list returned.
522      * </p>
523      * @see android.hardware.camera2.CameraManager
524      * @see android.hardware.camera2.CameraCharacteristics
525      *
526      * @param cameraId the id for the camera
527      * @param quality the target quality level for the camcorder profile
528      */
hasProfile(int cameraId, int quality)529     public static boolean hasProfile(int cameraId, int quality) {
530         return native_has_camcorder_profile(cameraId, quality);
531     }
532 
533     static {
534         System.loadLibrary("media_jni");
native_init()535         native_init();
536     }
537 
538     // 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)539     private CamcorderProfile(int duration,
540                              int quality,
541                              int fileFormat,
542                              int videoCodec,
543                              int videoBitRate,
544                              int videoFrameRate,
545                              int videoWidth,
546                              int videoHeight,
547                              int audioCodec,
548                              int audioBitRate,
549                              int audioSampleRate,
550                              int audioChannels) {
551 
552         this.duration         = duration;
553         this.quality          = quality;
554         this.fileFormat       = fileFormat;
555         this.videoCodec       = videoCodec;
556         this.videoBitRate     = videoBitRate;
557         this.videoFrameRate   = videoFrameRate;
558         this.videoFrameWidth  = videoWidth;
559         this.videoFrameHeight = videoHeight;
560         this.audioCodec       = audioCodec;
561         this.audioBitRate     = audioBitRate;
562         this.audioSampleRate  = audioSampleRate;
563         this.audioChannels    = audioChannels;
564     }
565 
566     // Methods implemented by JNI
567     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
native_init()568     private static native final void native_init();
569     @UnsupportedAppUsage
native_get_camcorder_profile( int cameraId, int quality)570     private static native final CamcorderProfile native_get_camcorder_profile(
571             int cameraId, int quality);
native_has_camcorder_profile( int cameraId, int quality)572     private static native final boolean native_has_camcorder_profile(
573             int cameraId, int quality);
574 }
575