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