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    // Start and end of quality list
94    private static final int QUALITY_LIST_START = QUALITY_LOW;
95    private static final int QUALITY_LIST_END = QUALITY_QVGA;
96
97    /**
98     * Time lapse quality level corresponding to the lowest available resolution.
99     */
100    public static final int QUALITY_TIME_LAPSE_LOW  = 1000;
101
102    /**
103     * Time lapse quality level corresponding to the highest available resolution.
104     */
105    public static final int QUALITY_TIME_LAPSE_HIGH = 1001;
106
107    /**
108     * Time lapse quality level corresponding to the qcif (176 x 144) resolution.
109     */
110    public static final int QUALITY_TIME_LAPSE_QCIF = 1002;
111
112    /**
113     * Time lapse quality level corresponding to the cif (352 x 288) resolution.
114     */
115    public static final int QUALITY_TIME_LAPSE_CIF = 1003;
116
117    /**
118     * Time lapse quality level corresponding to the 480p (720 x 480) resolution.
119     */
120    public static final int QUALITY_TIME_LAPSE_480P = 1004;
121
122    /**
123     * Time lapse quality level corresponding to the 720p (1280 x 720) resolution.
124     */
125    public static final int QUALITY_TIME_LAPSE_720P = 1005;
126
127    /**
128     * Time lapse quality level corresponding to the 1080p (1920 x 1088) resolution.
129     */
130    public static final int QUALITY_TIME_LAPSE_1080P = 1006;
131
132    /**
133     * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
134     */
135    public static final int QUALITY_TIME_LAPSE_QVGA = 1007;
136
137    // Start and end of timelapse quality list
138    private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
139    private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_QVGA;
140
141    /**
142     * Default recording duration in seconds before the session is terminated.
143     * This is useful for applications like MMS has limited file size requirement.
144     */
145    public int duration;
146
147    /**
148     * The quality level of the camcorder profile
149     */
150    public int quality;
151
152    /**
153     * The file output format of the camcorder profile
154     * @see android.media.MediaRecorder.OutputFormat
155     */
156    public int fileFormat;
157
158    /**
159     * The video encoder being used for the video track
160     * @see android.media.MediaRecorder.VideoEncoder
161     */
162    public int videoCodec;
163
164    /**
165     * The target video output bit rate in bits per second
166     */
167    public int videoBitRate;
168
169    /**
170     * The target video frame rate in frames per second
171     */
172    public int videoFrameRate;
173
174    /**
175     * The target video frame width in pixels
176     */
177    public int videoFrameWidth;
178
179    /**
180     * The target video frame height in pixels
181     */
182    public int videoFrameHeight;
183
184    /**
185     * The audio encoder being used for the audio track.
186     * @see android.media.MediaRecorder.AudioEncoder
187     */
188    public int audioCodec;
189
190    /**
191     * The target audio output bit rate in bits per second
192     */
193    public int audioBitRate;
194
195    /**
196     * The audio sampling rate used for the audio track
197     */
198    public int audioSampleRate;
199
200    /**
201     * The number of audio channels used for the audio track
202     */
203    public int audioChannels;
204
205    /**
206     * Returns the camcorder profile for the first back-facing camera on the
207     * device at the given quality level. If the device has no back-facing
208     * camera, this returns null.
209     * @param quality the target quality level for the camcorder profile
210     * @see #get(int, int)
211     */
212    public static CamcorderProfile get(int quality) {
213        int numberOfCameras = Camera.getNumberOfCameras();
214        CameraInfo cameraInfo = new CameraInfo();
215        for (int i = 0; i < numberOfCameras; i++) {
216            Camera.getCameraInfo(i, cameraInfo);
217            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
218                return get(i, quality);
219            }
220        }
221        return null;
222    }
223
224    /**
225     * Returns the camcorder profile for the given camera at the given
226     * quality level.
227     *
228     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
229     * other levels may or may not be supported. The supported levels can be checked using
230     * {@link #hasProfile(int, int)}.
231     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
232     * the highest quality available.
233     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, or 1080p.
234     * E.g. if the device supports 480p, 720p, and 1080p, then low is 480p and high is
235     * 1080p.
236     *
237     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
238     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
239     * qcif, cif, 480p, 720p, or 1080p.
240     *
241     * A camcorder recording session with higher quality level usually has higher output
242     * bit rate, better video and/or audio recording quality, larger video frame
243     * resolution and higher audio sampling rate, etc, than those with lower quality
244     * level.
245     *
246     * @param cameraId the id for the camera
247     * @param quality the target quality level for the camcorder profile.
248     * @see #QUALITY_LOW
249     * @see #QUALITY_HIGH
250     * @see #QUALITY_QCIF
251     * @see #QUALITY_CIF
252     * @see #QUALITY_480P
253     * @see #QUALITY_720P
254     * @see #QUALITY_1080P
255     * @see #QUALITY_TIME_LAPSE_LOW
256     * @see #QUALITY_TIME_LAPSE_HIGH
257     * @see #QUALITY_TIME_LAPSE_QCIF
258     * @see #QUALITY_TIME_LAPSE_CIF
259     * @see #QUALITY_TIME_LAPSE_480P
260     * @see #QUALITY_TIME_LAPSE_720P
261     * @see #QUALITY_TIME_LAPSE_1080P
262     */
263    public static CamcorderProfile get(int cameraId, int quality) {
264        if (!((quality >= QUALITY_LIST_START &&
265               quality <= QUALITY_LIST_END) ||
266              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
267               quality <= QUALITY_TIME_LAPSE_LIST_END))) {
268            String errMessage = "Unsupported quality level: " + quality;
269            throw new IllegalArgumentException(errMessage);
270        }
271        return native_get_camcorder_profile(cameraId, quality);
272    }
273
274    /**
275     * Returns true if camcorder profile exists for the first back-facing
276     * camera at the given quality level.
277     * @param quality the target quality level for the camcorder profile
278     */
279    public static boolean hasProfile(int quality) {
280        int numberOfCameras = Camera.getNumberOfCameras();
281        CameraInfo cameraInfo = new CameraInfo();
282        for (int i = 0; i < numberOfCameras; i++) {
283            Camera.getCameraInfo(i, cameraInfo);
284            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
285                return hasProfile(i, quality);
286            }
287        }
288        return false;
289    }
290
291    /**
292     * Returns true if camcorder profile exists for the given camera at
293     * the given quality level.
294     * @param cameraId the id for the camera
295     * @param quality the target quality level for the camcorder profile
296     */
297    public static boolean hasProfile(int cameraId, int quality) {
298        return native_has_camcorder_profile(cameraId, quality);
299    }
300
301    static {
302        System.loadLibrary("media_jni");
303        native_init();
304    }
305
306    // Private constructor called by JNI
307    private CamcorderProfile(int duration,
308                             int quality,
309                             int fileFormat,
310                             int videoCodec,
311                             int videoBitRate,
312                             int videoFrameRate,
313                             int videoWidth,
314                             int videoHeight,
315                             int audioCodec,
316                             int audioBitRate,
317                             int audioSampleRate,
318                             int audioChannels) {
319
320        this.duration         = duration;
321        this.quality          = quality;
322        this.fileFormat       = fileFormat;
323        this.videoCodec       = videoCodec;
324        this.videoBitRate     = videoBitRate;
325        this.videoFrameRate   = videoFrameRate;
326        this.videoFrameWidth  = videoWidth;
327        this.videoFrameHeight = videoHeight;
328        this.audioCodec       = audioCodec;
329        this.audioBitRate     = audioBitRate;
330        this.audioSampleRate  = audioSampleRate;
331        this.audioChannels    = audioChannels;
332    }
333
334    // Methods implemented by JNI
335    private static native final void native_init();
336    private static native final CamcorderProfile native_get_camcorder_profile(
337            int cameraId, int quality);
338    private static native final boolean native_has_camcorder_profile(
339            int cameraId, int quality);
340}
341