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