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