19b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong/*
29b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * Copyright (C) 2010 The Android Open Source Project
39b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong *
49b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * Licensed under the Apache License, Version 2.0 (the "License");
59b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * you may not use this file except in compliance with the License.
69b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * You may obtain a copy of the License at
79b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong *
89b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong *      http://www.apache.org/licenses/LICENSE-2.0
99b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong *
109b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * Unless required by applicable law or agreed to in writing, software
119b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * distributed under the License is distributed on an "AS IS" BASIS,
129b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * See the License for the specific language governing permissions and
149b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * limitations under the License.
159b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong */
169b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong
179b433f0b654d32530b0b48a7a653216ae0bb94d8James Dongpackage android.media;
189b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong
195680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Liimport android.hardware.Camera;
205680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Liimport android.hardware.Camera.CameraInfo;
215680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li
22e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dongimport java.util.Arrays;
2309b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Changimport java.util.HashMap;
24e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong
259b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong/**
269b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * The CameraProfile class is used to retrieve the pre-defined still image
279b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * capture (jpeg) quality levels (0-100) used for low, medium, and high
289b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong * quality settings in the Camera application.
299b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong *
309b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong */
319b433f0b654d32530b0b48a7a653216ae0bb94d8James Dongpublic class CameraProfile
329b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong{
339b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    /**
34e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * Define three quality levels for JPEG image encoding.
359b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong     */
36e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    /*
37e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * Don't change the values for these constants unless getImageEncodingQualityLevels()
38e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * method is also changed accordingly.
39e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     */
40e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    public static final int QUALITY_LOW    = 0;
41e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    public static final int QUALITY_MEDIUM = 1;
42e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    public static final int QUALITY_HIGH   = 2;
439b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong
44e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    /*
45e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * Cache the Jpeg encoding quality parameters
46e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     */
4709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    private static final HashMap<Integer, int[]> sCache = new HashMap<Integer, int[]>();
48e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong
49e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    /**
50e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * Returns a pre-defined still image capture (jpeg) quality level
5109b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * used for the given quality level in the Camera application for
525680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li     * the first back-facing camera on the device. If the device has no
535680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li     * back-facing camera, this returns 0.
54e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     *
55e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     * @param quality The target quality level
56e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong     */
57e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    public static int getJpegEncodingQualityParameter(int quality) {
585680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li        int numberOfCameras = Camera.getNumberOfCameras();
595680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li        CameraInfo cameraInfo = new CameraInfo();
605680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li        for (int i = 0; i < numberOfCameras; i++) {
615680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li            Camera.getCameraInfo(i, cameraInfo);
625680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
635680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li                return getJpegEncodingQualityParameter(i, quality);
645680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li            }
655680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li        }
665680635f39b3098539cbfd120f95fdc4479bab0fWu-cheng Li        return 0;
6709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    }
6809b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang
6909b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    /**
7009b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * Returns a pre-defined still image capture (jpeg) quality level
7109b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * used for the given quality level in the Camera application for
7209b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * the specified camera.
7309b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     *
7409b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * @param cameraId The id of the camera
7509b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     * @param quality The target quality level
7609b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang     */
7709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    public static int getJpegEncodingQualityParameter(int cameraId, int quality) {
78e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {
79e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong            throw new IllegalArgumentException("Unsupported quality level: " + quality);
809b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong        }
8109b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang        synchronized (sCache) {
8209b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang            int[] levels = sCache.get(cameraId);
8309b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang            if (levels == null) {
8409b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang                levels = getImageEncodingQualityLevels(cameraId);
8509b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang                sCache.put(cameraId, levels);
8609b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang            }
8709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang            return levels[quality];
8809b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang        }
899b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    }
909b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong
919b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    static {
929b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong        System.loadLibrary("media_jni");
939b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong        native_init();
94e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong    }
95e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong
9609b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    private static int[] getImageEncodingQualityLevels(int cameraId) {
9709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang        int nLevels = native_get_num_image_encoding_quality_levels(cameraId);
98e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        if (nLevels != QUALITY_HIGH + 1) {
99e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong            throw new RuntimeException("Unexpected Jpeg encoding quality levels " + nLevels);
100e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        }
101e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong
102e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        int[] levels = new int[nLevels];
103e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        for (int i = 0; i < nLevels; ++i) {
10409b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang            levels[i] = native_get_image_encoding_quality_level(cameraId, i);
105e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        }
106e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        Arrays.sort(levels);  // Lower quality level ALWAYS comes before higher one
107e64d9a236e4704abf53d3b7eea2eb066f23cf402James Dong        return levels;
1089b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    }
1099b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong
1109b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    // Methods implemented by JNI
1119b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong    private static native final void native_init();
11209b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    private static native final int native_get_num_image_encoding_quality_levels(int cameraId);
11309b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang    private static native final int native_get_image_encoding_quality_level(int cameraId, int index);
1149b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong}
115