19c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin/* 29c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Copyright (C) 2014 The Android Open Source Project 39c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 49c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 59c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * you may not use this file except in compliance with the License. 69c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * You may obtain a copy of the License at 79c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 89c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 99c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Unless required by applicable law or agreed to in writing, software 119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * See the License for the specific language governing permissions and 149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * limitations under the License. 159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinpackage android.hardware.camera2.params; 189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.graphics.ImageFormat; 209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.graphics.PixelFormat; 219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.CameraCharacteristics; 229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.CameraDevice; 239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.CaptureRequest; 249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.utils.HashCodeHelpers; 25fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvalaimport android.hardware.camera2.legacy.LegacyCameraDevice; 26fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvalaimport android.hardware.camera2.legacy.LegacyMetadataMapper; 27fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvalaimport android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException; 289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.view.Surface; 299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.util.Log; 3012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yehimport android.util.Range; 319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.util.Size; 329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport java.util.Arrays; 349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport java.util.HashMap; 359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport java.util.Objects; 36b0056642cab30647d1f72190d864622bf4728ea0Yin-Chia Yehimport java.util.Set; 379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport static com.android.internal.util.Preconditions.*; 399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin/** 419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Immutable class to store the available stream 42b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP configurations} to set up 43b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link android.view.Surface Surfaces} for creating a 44b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link android.hardware.camera2.CameraCaptureSession capture session} with 45b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link android.hardware.camera2.CameraDevice#createCaptureSession}. 469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <!-- TODO: link to input stream configuration --> 479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This is the authoritative list for all <!-- input/ -->output formats (and sizes respectively 499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for that format) that are supported by a camera device.</p> 509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This also contains the minimum frame durations and stall durations for each format/size 529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * combination that can be used to calculate effective frame rate when submitting multiple captures. 539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>An instance of this object is available from {@link CameraCharacteristics} using 569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP} key and the 579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link CameraCharacteristics#get} method.</p> 589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <pre><code>{@code 609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); 619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * StreamConfigurationMap configs = characteristics.get( 629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * }</code></pre> 649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP 66b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * @see CameraDevice#createCaptureSession 679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinpublic final class StreamConfigurationMap { 699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final String TAG = "StreamConfigurationMap"; 713e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk 723e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk /** 739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Create a new {@link StreamConfigurationMap}. 749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The array parameters ownership is passed to this object after creation; do not 769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * write to them after this constructor is invoked.</p> 779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param configurations a non-{@code null} array of {@link StreamConfiguration} 799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param minFrameDurations a non-{@code null} array of {@link StreamConfigurationDuration} 809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param stallDurations a non-{@code null} array of {@link StreamConfigurationDuration} 8112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if 8212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * camera device does not support high speed video recording 839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @throws NullPointerException if any of the arguments except highSpeedVideoConfigurations 8512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * were {@code null} or any subelements were {@code null} 869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @hide 889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public StreamConfigurationMap( 909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin StreamConfiguration[] configurations, 919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin StreamConfigurationDuration[] minFrameDurations, 9212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh StreamConfigurationDuration[] stallDurations, 9312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh HighSpeedVideoConfiguration[] highSpeedVideoConfigurations) { 949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin mConfigurations = checkArrayElementsNotNull(configurations, "configurations"); 969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations"); 979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations"); 9812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (highSpeedVideoConfigurations == null) { 9912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mHighSpeedVideoConfigurations = new HighSpeedVideoConfiguration[0]; 10012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } else { 10112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mHighSpeedVideoConfigurations = checkArrayElementsNotNull( 10212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh highSpeedVideoConfigurations, "highSpeedVideoConfigurations"); 10312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 1049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // For each format, track how many sizes there are available to configure 1069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (StreamConfiguration config : configurations) { 1079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin HashMap<Integer, Integer> map = config.isOutput() ? mOutputFormats : mInputFormats; 1089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin Integer count = map.get(config.getFormat()); 1109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (count == null) { 1129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin count = 0; 1139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin count = count + 1; 1159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin map.put(config.getFormat(), count); 1179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (!mOutputFormats.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { 1209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new AssertionError( 1219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "At least one stream configuration for IMPLEMENTATION_DEFINED must exist"); 1229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 12312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 12412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh // For each Size/FPS range, track how many FPS range/Size there are available 12512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { 12612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Size size = config.getSize(); 12712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Range<Integer> fpsRange = config.getFpsRange(); 12812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size); 12912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (fpsRangeCount == null) { 13012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh fpsRangeCount = 0; 13112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 13212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mHighSpeedVideoSizeMap.put(size, fpsRangeCount + 1); 13312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Integer sizeCount = mHighSpeedVideoFpsRangeMap.get(fpsRange); 13412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (sizeCount == null) { 13512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh sizeCount = 0; 13612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 13712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mHighSpeedVideoFpsRangeMap.put(fpsRange, sizeCount + 1); 13812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 1399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 1429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the image {@code format} output formats in this stream configuration. 1439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>All image formats returned by this function will be defined in either {@link ImageFormat} 1459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * or in {@link PixelFormat} (and there is no possibility of collision).</p> 1469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Formats listed in this array are guaranteed to return true if queried with 148f3621f3a5c5fd16ebedd3ce1ae1b0100d0f64152Eino-Ville Talvala * {@link #isOutputSupportedFor(int)}.</p> 1499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return an array of integer format 1519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 1539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 1549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 1559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public final int[] getOutputFormats() { 1569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getPublicFormats(/*output*/true); 1579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 1609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the image {@code format} input formats in this stream configuration. 1619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>All image formats returned by this function will be defined in either {@link ImageFormat} 1639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * or in {@link PixelFormat} (and there is no possibility of collision).</p> 1649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return an array of integer format 1669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 1689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 1699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @hide 1719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 1729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public final int[] getInputFormats() { 1739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getPublicFormats(/*output*/false); 1749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 1779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the supported input sizes for this input format. 1789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The format must have come from {@link #getInputFormats}; otherwise 1809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code null} is returned.</p> 1819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format a format from {@link #getInputFormats} 1839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return a non-empty array of sizes, or {@code null} if the format was not available. 1849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @hide 1869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 1879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public Size[] getInputSizes(final int format) { 1889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getPublicFormatSizes(format, /*output*/false); 1899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 1919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 192b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * Determine whether or not output surfaces with a particular user-defined format can be passed 193b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link CameraDevice#createCaptureSession createCaptureSession}. 1949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This method determines that the output {@code format} is supported by the camera device; 1969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * each output {@code surface} target may or may not itself support that {@code format}. 1979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Refer to the class which provides the surface for additional documentation.</p> 1989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 1999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Formats for which this returns {@code true} are guaranteed to exist in the result 2009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * returned by {@link #getOutputSizes}.</p> 2019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format an image format from either {@link ImageFormat} or {@link PixelFormat} 2039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return 2049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code true} iff using a {@code surface} with this {@code format} will be 205b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * supported with {@link CameraDevice#createCaptureSession} 2069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException 2089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * if the image format was not a defined named constant 2099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * from either {@link ImageFormat} or {@link PixelFormat} 2109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 2129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 213b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * @see CameraDevice#createCaptureSession 2149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 2159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public boolean isOutputSupportedFor(int format) { 2169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkArgumentFormat(format); 2179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 2189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin format = imageFormatToInternal(format); 2199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getFormatsMap(/*output*/true).containsKey(format); 2209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 2219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 2229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 2239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Determine whether or not output streams can be configured with a particular class 2249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * as a consumer. 2259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The following list is generally usable for outputs: 2279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 2289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.media.ImageReader} - 2299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for image processing or streaming to external resources (such as a file or 2309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * network) 2319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.media.MediaRecorder} - 2329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for recording video (simple to use) 2339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.media.MediaCodec} - 2349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for recording video (more complicated to use, with more flexibility) 2359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.renderscript.Allocation} - 2369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for image processing with {@link android.renderscript RenderScript} 2379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.view.SurfaceHolder} - 2389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for low-power camera preview with {@link android.view.SurfaceView} 2399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link android.graphics.SurfaceTexture} - 2409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Recommended for OpenGL-accelerated preview processing or compositing with 2419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link android.view.TextureView} 2429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 2439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 2449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Generally speaking this means that creating a {@link Surface} from that class <i>may</i> 2469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * provide a producer endpoint that is suitable to be used with 247b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * {@link CameraDevice#createCaptureSession}.</p> 2489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Since not all of the above classes support output of all format and size combinations, 2509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * the particular combination should be queried with {@link #isOutputSupportedFor(Surface)}.</p> 2519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param klass a non-{@code null} {@link Class} object reference 2539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return {@code true} if this class is supported as an output, {@code false} otherwise 2549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code klass} was {@code null} 2569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 257b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * @see CameraDevice#createCaptureSession 2589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #isOutputSupportedFor(Surface) 2599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 2609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public static <T> boolean isOutputSupportedFor(Class<T> klass) { 2619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkNotNull(klass, "klass must not be null"); 2629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 2639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (klass == android.media.ImageReader.class) { 2649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } else if (klass == android.media.MediaRecorder.class) { 2669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } else if (klass == android.media.MediaCodec.class) { 2689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } else if (klass == android.renderscript.Allocation.class) { 2709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } else if (klass == android.view.SurfaceHolder.class) { 2729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } else if (klass == android.graphics.SurfaceTexture.class) { 2749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 2759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 2769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 2779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return false; 2789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 2799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 2809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 281b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * Determine whether or not the {@code surface} in its current state is suitable to be included 282b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * in a {@link CameraDevice#createCaptureSession capture session} as an output. 2839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Not all surfaces are usable with the {@link CameraDevice}, and not all configurations 2859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * of that {@code surface} are compatible. Some classes that provide the {@code surface} are 2869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * compatible with the {@link CameraDevice} in general 2879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * (see {@link #isOutputSupportedFor(Class)}, but it is the caller's responsibility to put the 2889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code surface} into a state that will be compatible with the {@link CameraDevice}.</p> 2899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 2909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Reasons for a {@code surface} being specifically incompatible might be: 2919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 2929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>Using a format that's not listed by {@link #getOutputFormats} 2939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>Using a format/size combination that's not listed by {@link #getOutputSizes} 2949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>The {@code surface} itself is not in a state where it can service a new producer.</p> 2959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </li> 2969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 2979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 298fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * <p>Surfaces from flexible sources will return true even if the exact size of the Surface does 299fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * not match a camera-supported size, as long as the format (or class) is supported and the 300fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * camera device supports a size that is equal to or less than 1080p in that format. If such as 301fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * Surface is used to create a capture session, it will have its size rounded to the nearest 302fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * supported size, below or equal to 1080p. Flexible sources include SurfaceView, SurfaceTexture, 303fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * and ImageReader.</p> 304fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * 305fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * <p>This is not an exhaustive list; see the particular class's documentation for further 3069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * possible reasons of incompatibility.</p> 3079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param surface a non-{@code null} {@link Surface} object reference 3099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return {@code true} if this is supported, {@code false} otherwise 3109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code surface} was {@code null} 312fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * @throws IllegalArgumentException if the Surface endpoint is no longer valid 3139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 314b67a3b36fd569e63c1b8ca6b2701c34c7a3927c1Eino-Ville Talvala * @see CameraDevice#createCaptureSession 3159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #isOutputSupportedFor(Class) 3169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 3179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public boolean isOutputSupportedFor(Surface surface) { 3189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkNotNull(surface, "surface must not be null"); 3199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 320fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala Size surfaceSize; 321fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala int surfaceFormat = -1; 322fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala try { 323fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala surfaceSize = LegacyCameraDevice.getSurfaceSize(surface); 324fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala surfaceFormat = LegacyCameraDevice.detectSurfaceType(surface); 325fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } catch(BufferQueueAbandonedException e) { 326fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala throw new IllegalArgumentException("Abandoned surface", e); 327fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 328fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala 329fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // See if consumer is flexible. 330fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface); 3319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 332fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // Override RGB formats to IMPLEMENTATION_DEFINED, b/9487482 333fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala if ((surfaceFormat >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 && 334fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala surfaceFormat <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) { 335fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala surfaceFormat = LegacyMetadataMapper.HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 336fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 337fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala 338fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala for (StreamConfiguration config : mConfigurations) { 339fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala if (config.getFormat() == surfaceFormat && config.isOutput()) { 340fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // Mathing format, either need exact size match, or a flexible consumer 341fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // and a size no bigger than MAX_DIMEN_FOR_ROUNDING 342fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala if (config.getSize().equals(surfaceSize)) { 343fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala return true; 344fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } else if (isFlexible && 345fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala (config.getSize().getWidth() <= LegacyCameraDevice.MAX_DIMEN_FOR_ROUNDING)) { 346fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala return true; 347fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 348fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 349fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 350fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala return false; 3519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 3529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 3539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 3549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get a list of sizes compatible with {@code klass} to use as an output. 3559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Since some of the supported classes may support additional formats beyond 3579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * an opaque/implementation-defined (under-the-hood) format; this function only returns 3589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * sizes for the implementation-defined format.</p> 3599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Some classes such as {@link android.media.ImageReader} may only support user-defined 3619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * formats; in particular {@link #isOutputSupportedFor(Class)} will return {@code true} for 3629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * that class and this method will return an empty array (but not {@code null}).</p> 3639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>If a well-defined format such as {@code NV21} is required, use 3659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(int)} instead.</p> 3669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The {@code klass} should be a supported output, that querying 3689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code #isOutputSupportedFor(Class)} should return {@code true}.</p> 3699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param klass 3719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * a non-{@code null} {@link Class} object reference 3729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return 3739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * an array of supported sizes for implementation-defined formats, 3749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * or {@code null} iff the {@code klass} is not a supported output 3759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code klass} was {@code null} 3779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #isOutputSupportedFor(Class) 3799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 3809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public <T> Size[] getOutputSizes(Class<T> klass) { 381517b74533afe53c740400bff3b85806884286344Igor Murashkin // Image reader is "supported", but never for implementation-defined formats; return empty 382517b74533afe53c740400bff3b85806884286344Igor Murashkin if (android.media.ImageReader.class.isAssignableFrom(klass)) { 383517b74533afe53c740400bff3b85806884286344Igor Murashkin return new Size[0]; 384517b74533afe53c740400bff3b85806884286344Igor Murashkin } 385517b74533afe53c740400bff3b85806884286344Igor Murashkin 3869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (isOutputSupportedFor(klass) == false) { 3879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return null; 3889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 3899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 3909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, /*output*/true); 3919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 3929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 3939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 3949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get a list of sizes compatible with the requested image {@code format}. 3959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The {@code format} should be a supported format (one of the formats returned by 3979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputFormats}).</p> 3989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 3999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format an image format from {@link ImageFormat} or {@link PixelFormat} 4009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return 4019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * an array of supported sizes, 4029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * or {@code null} if the {@code format} is not a supported output 4039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 4049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 4059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 4069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #getOutputFormats 4079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 4089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public Size[] getOutputSizes(int format) { 4099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getPublicFormatSizes(format, /*output*/true); 4109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 4119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 4129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 41312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Get a list of supported high speed video recording sizes. 41412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 41512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> When HIGH_SPEED_VIDEO is supported in 41612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this 41712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * method will list the supported high speed video size configurations. All the sizes listed 41812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * will be a subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling 41912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * formats (typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12)</p> 42012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 42112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> To enable high speed video recording, application must set 42212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE} to 42312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture 42412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * requests and select the video size from this method and 42512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from 42612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link #getHighSpeedVideoFpsRangesFor} to configure the recording and preview streams and 42712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * setup the recording requests. For example, if the application intends to do high speed 42812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * recording, it can select the maximum size reported by this method to configure output 42912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * streams. Note that for the use case of multiple output streams, application must select one 43012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * unique size from this method to use. Otherwise a request error might occur. Once the size is 43112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * selected, application can get the supported FPS ranges by 43212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link #getHighSpeedVideoFpsRangesFor}, and use these FPS ranges to setup the recording 43312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * requests.</p> 43412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 43512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @return 43612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * an array of supported high speed video recording sizes 43712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 43812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @see #getHighSpeedVideoFpsRangesFor(Size) 43912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh */ 44012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh public Size[] getHighSpeedVideoSizes() { 441b0056642cab30647d1f72190d864622bf4728ea0Yin-Chia Yeh Set<Size> keySet = mHighSpeedVideoSizeMap.keySet(); 442b0056642cab30647d1f72190d864622bf4728ea0Yin-Chia Yeh return keySet.toArray(new Size[keySet.size()]); 44312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 44412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 44512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** 44612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size. 44712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 44812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p> 44912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 45012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> For normal video recording use case, where some application will NOT set 45112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE} to 45212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture 45312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in 45412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * this method must not be used to setup capture requests, or it will cause request error.</p> 45512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 45612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()} 45712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @return 45812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * An array of FPS range to use with 45912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE TARGET_FPS_RANGE} when using 46012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene 46112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * mode. 46212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * The upper bound of returned ranges is guaranteed to be larger or equal to 60. 46312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 46412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @throws IllegalArgumentException if input size does not exist in the return value of 46512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * getHighSpeedVideoSizes 46612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @see #getHighSpeedVideoSizes() 46712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh */ 46812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh public Range<Integer>[] getHighSpeedVideoFpsRangesFor(Size size) { 46912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size); 47012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (fpsRangeCount == null || fpsRangeCount == 0) { 47112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh throw new IllegalArgumentException(String.format( 47212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh "Size %s does not support high speed video recording", size)); 47312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 47412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 47512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh @SuppressWarnings("unchecked") 47612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Range<Integer>[] fpsRanges = new Range[fpsRangeCount]; 47712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh int i = 0; 47812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { 47912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (size.equals(config.getSize())) { 48012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh fpsRanges[i++] = config.getFpsRange(); 48112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 48212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 48312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh return fpsRanges; 48412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 48512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 48612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** 48712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Get a list of supported high speed video recording FPS ranges. 48812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 48912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> When HIGH_SPEED_VIDEO is supported in 49012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this 49112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * method will list the supported high speed video FPS range configurations. Application can 49212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * then use {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned 49312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * FPS range.</p> 49412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 49512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> To enable high speed video recording, application must set 49612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE} to 49712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture 49812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * requests and select the video size from {@link #getHighSpeedVideoSizesFor} and 49912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from 50012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * this method to configure the recording and preview streams and setup the recording requests. 50112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * For example, if the application intends to do high speed recording, it can select one FPS 50212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * range reported by this method, query the video sizes corresponding to this FPS range by 50312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link #getHighSpeedVideoSizesFor} and select one of reported sizes to configure output 50412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * streams. Note that for the use case of multiple output streams, application must select one 50512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * unique size from {@link #getHighSpeedVideoSizesFor}, and use it for all output streams. 50612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Otherwise a request error might occur when attempting to enable 50712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}. 50812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Once the stream is configured, application can set the FPS range in the recording requests. 50912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * </p> 51012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 51112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @return 51212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * an array of supported high speed video recording FPS ranges 51312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * The upper bound of returned ranges is guaranteed to be larger or equal to 60. 51412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 51512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @see #getHighSpeedVideoSizesFor 51612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh */ 51712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh @SuppressWarnings("unchecked") 51812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh public Range<Integer>[] getHighSpeedVideoFpsRanges() { 519b0056642cab30647d1f72190d864622bf4728ea0Yin-Chia Yeh Set<Range<Integer>> keySet = mHighSpeedVideoFpsRangeMap.keySet(); 520b0056642cab30647d1f72190d864622bf4728ea0Yin-Chia Yeh return keySet.toArray(new Range[keySet.size()]); 52112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 52212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 52312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** 52412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * Get the supported video sizes for input FPS range. 52512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 52612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.</p> 52712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 52812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * <p> For normal video recording use case, where the application will NOT set 52912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE} to 53012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture 53112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in 53212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * this method must not be used to setup capture requests, or it will cause request error.</p> 53312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 53412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()} 53512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @return 53612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * An array of video sizes to configure output stream when using 53712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene 53812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * mode. 53912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * 54012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @throws IllegalArgumentException if input FPS range does not exist in the return value of 54112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * getHighSpeedVideoFpsRanges 54212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh * @see #getHighSpeedVideoFpsRanges() 54312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh */ 54412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh public Size[] getHighSpeedVideoSizesFor(Range<Integer> fpsRange) { 54512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Integer sizeCount = mHighSpeedVideoFpsRangeMap.get(fpsRange); 54612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (sizeCount == null || sizeCount == 0) { 54712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh throw new IllegalArgumentException(String.format( 54812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh "FpsRange %s does not support high speed video recording", fpsRange)); 54912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 55012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 55112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Size[] sizes = new Size[sizeCount]; 55212da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh int i = 0; 55312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { 55412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh if (fpsRange.equals(config.getFpsRange())) { 55512da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh sizes[i++] = config.getSize(); 55612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 55712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 55812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh return sizes; 55912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh } 56012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh 56112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** 5629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration} 5639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for the format/size combination (in nanoseconds). 5649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code format} should be one of the ones returned by {@link #getOutputFormats()}.</p> 5669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code size} should be one of the ones returned by 5679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(int)}.</p> 5689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This should correspond to the frame duration when only that stream is active, with all 5709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * processing (typically in {@code android.*.mode}) set to either {@code OFF} or {@code FAST}. 5719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 5729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>When multiple streams are used in a request, the minimum frame duration will be 5749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code max(individual stream min durations)}.</p> 5759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 57608bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * <p>For devices that do not support manual sensor control 57708bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * ({@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR}), 578abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala * this function may return 0.</p> 57908bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * 5809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <!-- 5819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * TODO: uncomment after adding input stream support 5829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The minimum frame duration of a stream (of a particular format, size) is the same 5839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * regardless of whether the stream is input or output.</p> 5849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * --> 5859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format an image format from {@link ImageFormat} or {@link PixelFormat} 5879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param size an output-compatible size 5883e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk * @return a minimum frame duration {@code >} 0 in nanoseconds, or 589abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala * 0 if the minimum frame duration is not available. 5909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if {@code format} or {@code size} was not supported 5929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code size} was {@code null} 5939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 5949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see CaptureRequest#SENSOR_FRAME_DURATION 5959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #getOutputStallDuration(int, Size) 5969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 5979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 5989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 5999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public long getOutputMinFrameDuration(int format, Size size) { 6009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkNotNull(size, "size must not be null"); 6019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkArgumentFormatSupported(format, /*output*/true); 6029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 6039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatDuration(imageFormatToInternal(format), size, DURATION_MIN_FRAME); 6049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 6059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 6069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 6079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration} 6089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for the class/size combination (in nanoseconds). 6099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This assumes a the {@code klass} is set up to use an implementation-defined format. 6119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * For user-defined formats, use {@link #getOutputMinFrameDuration(int, Size)}.</p> 6129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code klass} should be one of the ones which is supported by 6149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #isOutputSupportedFor(Class)}.</p> 6159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code size} should be one of the ones returned by 6179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(int)}.</p> 6189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This should correspond to the frame duration when only that stream is active, with all 6209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * processing (typically in {@code android.*.mode}) set to either {@code OFF} or {@code FAST}. 6219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 6229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>When multiple streams are used in a request, the minimum frame duration will be 6249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code max(individual stream min durations)}.</p> 6259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 62608bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * <p>For devices that do not support manual sensor control 62708bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * ({@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR}), 628abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala * this function may return 0.</p> 62908bc3b0f0299a02d00004f4b2886469c1ed75569Eino-Ville Talvala * 6309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <!-- 6319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * TODO: uncomment after adding input stream support 6329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The minimum frame duration of a stream (of a particular format, size) is the same 6339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * regardless of whether the stream is input or output.</p> 6349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * --> 6359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param klass 6379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * a class which is supported by {@link #isOutputSupportedFor(Class)} and has a 6389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * non-empty array returned by {@link #getOutputSizes(Class)} 6399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param size an output-compatible size 6403e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk * @return a minimum frame duration {@code >} 0 in nanoseconds, or 641abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala * 0 if the minimum frame duration is not available. 6429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported 6449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code size} or {@code klass} was {@code null} 6459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see CaptureRequest#SENSOR_FRAME_DURATION 6479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 6489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 6499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 6509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public <T> long getOutputMinFrameDuration(final Class<T> klass, final Size size) { 6519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (!isOutputSupportedFor(klass)) { 6529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException("klass was not supported"); 6539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 6549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 6559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatDuration(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 6569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin size, DURATION_MIN_FRAME); 6579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 6589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 6599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 6609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the stall duration for the format/size combination (in nanoseconds). 6619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code format} should be one of the ones returned by {@link #getOutputFormats()}.</p> 6639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code size} should be one of the ones returned by 6649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(int)}.</p> 6659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p> 6679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * A stall duration is how much extra time would get added to the normal minimum frame duration 6689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for a repeating request that has streams with non-zero stall. 6699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>For example, consider JPEG captures which have the following characteristics: 6719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 6739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>JPEG streams act like processed YUV streams in requests for which they are not included; 6749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * in requests in which they are directly referenced, they act as JPEG streams. 6759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * This is because supporting a JPEG stream requires the underlying YUV data to always be ready 6769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for use by a JPEG encoder, but the encoder will only be used (and impact frame duration) on 6779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * requests that actually reference a JPEG stream. 6789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>The JPEG processor can run concurrently to the rest of the camera pipeline, but cannot 6799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * process more than 1 capture at a time. 6809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 6819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>In other words, using a repeating YUV request would result in a steady frame rate 6839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * (let's say it's 30 FPS). If a single JPEG request is submitted periodically, 6849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * the frame rate will stay at 30 FPS (as long as we wait for the previous JPEG to return each 6859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * time). If we try to submit a repeating YUV + JPEG request, then the frame rate will drop from 6869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 30 FPS.</p> 6879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>In general, submitting a new request with a non-0 stall time stream will <em>not</em> cause a 6899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * frame rate drop unless there are still outstanding buffers for that stream from previous 6909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * requests.</p> 6919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Submitting a repeating request with streams (call this {@code S}) is the same as setting 6939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * the minimum frame duration from the normal minimum frame duration corresponding to {@code S}, 6949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * added with the maximum stall duration for {@code S}.</p> 6959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>If interleaving requests with and without a stall duration, a request will stall by the 6979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * maximum of the remaining times for each can-stall stream with outstanding buffers.</p> 6989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 6999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This means that a stalling request will not have an exposure start until the stall has 7009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * completed.</p> 7019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This should correspond to the stall duration when only that stream is active, with all 7039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * processing (typically in {@code android.*.mode}) set to {@code FAST} or {@code OFF}. 7049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Setting any of the processing modes to {@code HIGH_QUALITY} effectively results in an 7059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * indeterminate stall duration for all streams in a request (the regular stall calculation 7069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * rules are ignored).</p> 7079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The following formats may always have a stall duration: 7099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 7109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link ImageFormat#JPEG JPEG} 7119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link ImageFormat#RAW_SENSOR RAW16} 7129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 7139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 7149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>The following formats will never have a stall duration: 7169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 7179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link ImageFormat#YUV_420_888 YUV_420_888} 7189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>{@link #isOutputSupportedFor(Class) Implementation-Defined} 7199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul></p> 7209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p> 7229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * All other formats may or may not have an allowed stall duration on a per-capability basis; 7239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES 7249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * android.request.availableCapabilities} for more details.</p> 7259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 7269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} 7289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * for more information about calculating the max frame rate (absent stalls).</p> 7299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format an image format from {@link ImageFormat} or {@link PixelFormat} 7319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param size an output-compatible size 7329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return a stall duration {@code >=} 0 in nanoseconds 7339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if {@code format} or {@code size} was not supported 7359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code size} was {@code null} 7369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see CaptureRequest#SENSOR_FRAME_DURATION 7389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 7399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 7409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 7419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public long getOutputStallDuration(int format, Size size) { 7429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkArgumentFormatSupported(format, /*output*/true); 7439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 7449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatDuration(imageFormatToInternal(format), 7459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin size, DURATION_STALL); 7469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 7479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 7489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 7499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the stall duration for the class/size combination (in nanoseconds). 7509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This assumes a the {@code klass} is set up to use an implementation-defined format. 7529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * For user-defined formats, use {@link #getOutputMinFrameDuration(int, Size)}.</p> 7539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code klass} should be one of the ones with a non-empty array returned by 7559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(Class)}.</p> 7569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>{@code size} should be one of the ones returned by 7589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link #getOutputSizes(Class)}.</p> 7599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>See {@link #getOutputStallDuration(int, Size)} for a definition of a 7619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <em>stall duration</em>.</p> 7629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param klass 7649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * a class which is supported by {@link #isOutputSupportedFor(Class)} and has a 7659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * non-empty array returned by {@link #getOutputSizes(Class)} 7669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param size an output-compatible size 7679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return a minimum frame duration {@code >=} 0 in nanoseconds 7689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported 7709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws NullPointerException if {@code size} or {@code klass} was {@code null} 7719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see CaptureRequest#SENSOR_FRAME_DURATION 7739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 7749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 7759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 7769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public <T> long getOutputStallDuration(final Class<T> klass, final Size size) { 7779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (!isOutputSupportedFor(klass)) { 7789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException("klass was not supported"); 7799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 7809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 7819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatDuration(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 7829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin size, DURATION_STALL); 7839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 7849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 7859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 7869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Check if this {@link StreamConfigurationMap} is equal to another 7879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link StreamConfigurationMap}. 7889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Two vectors are only equal if and only if each of the respective elements is equal.</p> 7909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 7919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return {@code true} if the objects were equal, {@code false} otherwise 7929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 7939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin @Override 7949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public boolean equals(final Object obj) { 7959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (obj == null) { 7969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return false; 7979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 7989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (this == obj) { 7999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 8009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (obj instanceof StreamConfigurationMap) { 8029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin final StreamConfigurationMap other = (StreamConfigurationMap) obj; 8039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // XX: do we care about order? 8049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return Arrays.equals(mConfigurations, other.mConfigurations) && 8059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin Arrays.equals(mMinFrameDurations, other.mMinFrameDurations) && 80612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Arrays.equals(mStallDurations, other.mStallDurations) && 80712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh Arrays.equals(mHighSpeedVideoConfigurations, 80812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh other.mHighSpeedVideoConfigurations); 8099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return false; 8119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 8149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@inheritDoc} 8159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 8169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin @Override 8179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public int hashCode() { 8189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // XX: do we care about order? 81912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh return HashCodeHelpers.hashCode( 82012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mConfigurations, mMinFrameDurations, 82112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mStallDurations, mHighSpeedVideoConfigurations); 8229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // Check that the argument is supported by #getOutputFormats or #getInputFormats 8259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private int checkArgumentFormatSupported(int format, boolean output) { 8269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkArgumentFormat(format); 8279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int[] formats = output ? getOutputFormats() : getInputFormats(); 8299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (int i = 0; i < formats.length; ++i) { 8309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (format == formats[i]) { 8319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return format; 8329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException(String.format( 8369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "format %x is not supported by this stream configuration map", format)); 8379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 8409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Ensures that the format is either user-defined or implementation defined. 8419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>If a format has a different internal representation than the public representation, 8439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * passing in the public representation here will fail.</p> 8449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>For example if trying to use {@link ImageFormat#JPEG}: 8469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * it has a different public representation than the internal representation 8479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@code HAL_PIXEL_FORMAT_BLOB}, this check will fail.</p> 8489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Any invalid/undefined formats will raise an exception.</p> 8509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format image format 8529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return the format 8539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if the format was invalid 8559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 8569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin static int checkArgumentFormatInternal(int format) { 8579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin switch (format) { 8589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 8599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case HAL_PIXEL_FORMAT_BLOB: 860d3b85f69a811113826933c8abf591f20e9b3c8ffEino-Ville Talvala case HAL_PIXEL_FORMAT_RAW_OPAQUE: 8619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return format; 8629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case ImageFormat.JPEG: 8639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException( 8649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "ImageFormat.JPEG is an unknown internal format"); 8659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin default: 8669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return checkArgumentFormat(format); 8679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 8719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Ensures that the format is publicly user-defined in either ImageFormat or PixelFormat. 8729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>If a format has a different public representation than the internal representation, 8749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * passing in the internal representation here will fail.</p> 8759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>For example if trying to use {@code HAL_PIXEL_FORMAT_BLOB}: 8779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * it has a different internal representation than the public representation 8789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link ImageFormat#JPEG}, this check will fail.</p> 8799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Any invalid/undefined formats will raise an exception, including implementation-defined. 8819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 8829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Note that {@code @hide} and deprecated formats will not pass this check.</p> 8849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format image format 8869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return the format 8879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 8889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException if the format was not user-defined 8899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 8909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin static int checkArgumentFormat(int format) { 8919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (!ImageFormat.isPublicFormat(format) && !PixelFormat.isPublicFormat(format)) { 8929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException(String.format( 8939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "format 0x%x was not defined in either ImageFormat or PixelFormat", format)); 8949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return format; 8979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 8989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 8999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 9009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Convert a public-visible {@code ImageFormat} into an internal format 9019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * compatible with {@code graphics.h}. 9029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>In particular these formats are converted: 9049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 9059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>HAL_PIXEL_FORMAT_BLOB => ImageFormat.JPEG 9069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 9079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 9089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Passing in an implementation-defined format which has no public equivalent will fail; 9109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * as will passing in a public format which has a different internal format equivalent. 9119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * See {@link #checkArgumentFormat} for more details about a legal public format.</p> 9129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>All other formats are returned as-is, no further invalid check is performed.</p> 9149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This function is the dual of {@link #imageFormatToInternal}.</p> 9169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format image format from {@link ImageFormat} or {@link PixelFormat} 9189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return the converted image formats 9199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException 9219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * if {@code format} is {@code HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED} or 9229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * {@link ImageFormat#JPEG} 9239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 9259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 9269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #checkArgumentFormat 9279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 9289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin static int imageFormatToPublic(int format) { 9299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin switch (format) { 9309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case HAL_PIXEL_FORMAT_BLOB: 9319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return ImageFormat.JPEG; 9329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case ImageFormat.JPEG: 9339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException( 9349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "ImageFormat.JPEG is an unknown internal format"); 9359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 9369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException( 9379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "IMPLEMENTATION_DEFINED must not leak to public API"); 9389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin default: 9399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return format; 9409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 9419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 9429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 9439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 9449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Convert image formats from internal to public formats (in-place). 9459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param formats an array of image formats 9479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return {@code formats} 9489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #imageFormatToPublic 9509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 9519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin static int[] imageFormatToPublic(int[] formats) { 9529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (formats == null) { 9539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return null; 9549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 9559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 9569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (int i = 0; i < formats.length; ++i) { 9579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin formats[i] = imageFormatToPublic(formats[i]); 9589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 9599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 9609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return formats; 9619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 9629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 9639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 9649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Convert a public format compatible with {@code ImageFormat} to an internal format 9659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * from {@code graphics.h}. 9669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>In particular these formats are converted: 9689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <ul> 9699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <li>ImageFormat.JPEG => HAL_PIXEL_FORMAT_BLOB 9709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </ul> 9719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * </p> 9729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>Passing in an implementation-defined format here will fail (it's not a public format); 9749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * as will passing in an internal format which has a different public format equivalent. 9759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * See {@link #checkArgumentFormat} for more details about a legal public format.</p> 9769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>All other formats are returned as-is, no invalid check is performed.</p> 9789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * <p>This function is the dual of {@link #imageFormatToPublic}.</p> 9809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param format public image format from {@link ImageFormat} or {@link PixelFormat} 9829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return the converted image formats 9839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see ImageFormat 9859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see PixelFormat 9869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 9879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @throws IllegalArgumentException 9889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * if {@code format} was {@code HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED} 9899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 9909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin static int imageFormatToInternal(int format) { 9919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin switch (format) { 9929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case ImageFormat.JPEG: 9939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return HAL_PIXEL_FORMAT_BLOB; 9949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 9959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException( 9969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "IMPLEMENTATION_DEFINED is not allowed via public API"); 9979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin default: 9989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return format; 9999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 10039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Convert image formats from public to internal formats (in-place). 10049c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 10059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @param formats an array of image formats 10069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @return {@code formats} 10079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 10089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #imageFormatToInternal 10099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 10109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @hide 10119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 10129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin public static int[] imageFormatToInternal(int[] formats) { 10139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (formats == null) { 10149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return null; 10159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (int i = 0; i < formats.length; ++i) { 10189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin formats[i] = imageFormatToInternal(formats[i]); 10199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return formats; 10229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private Size[] getPublicFormatSizes(int format, boolean output) { 10259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin try { 10269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin checkArgumentFormatSupported(format, output); 10279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } catch (IllegalArgumentException e) { 10289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return null; 10299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin format = imageFormatToInternal(format); 10329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10339c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return getInternalFormatSizes(format, output); 10349c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private Size[] getInternalFormatSizes(int format, boolean output) { 10379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin HashMap<Integer, Integer> formatsMap = getFormatsMap(output); 10389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin Integer sizesCount = formatsMap.get(format); 10409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (sizesCount == null) { 10419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException("format not available"); 10429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int len = sizesCount; 10459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin Size[] sizes = new Size[len]; 10469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int sizeIndex = 0; 10479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (StreamConfiguration config : mConfigurations) { 10499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (config.getFormat() == format && config.isOutput() == output) { 10509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin sizes[sizeIndex++] = config.getSize(); 10519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (sizeIndex != len) { 10559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new AssertionError( 10569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin "Too few sizes (expected " + len + ", actual " + sizeIndex + ")"); 10579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return sizes; 10609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** Get the list of publically visible output formats; does not include IMPL_DEFINED */ 10639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private int[] getPublicFormats(boolean output) { 10649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int[] formats = new int[getPublicFormatCount(output)]; 10659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int i = 0; 10679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10689c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (int format : getFormatsMap(output).keySet()) { 1069fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && 1070fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala format != HAL_PIXEL_FORMAT_RAW_OPAQUE) { 10719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin formats[i++] = format; 10729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (formats.length != i) { 10769c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new AssertionError("Too few formats " + i + ", expected " + formats.length); 10779c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10789c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return imageFormatToPublic(formats); 10809c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10819c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** Get the format -> size count map for either output or input formats */ 10839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private HashMap<Integer, Integer> getFormatsMap(boolean output) { 10849c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return output ? mOutputFormats : mInputFormats; 10859c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10879c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private long getInternalFormatDuration(int format, Size size, int duration) { 10889c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // assume format is already checked, since its internal 10899c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10909c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (!arrayContains(getInternalFormatSizes(format, /*output*/true), size)) { 10919c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException("size was not supported"); 10929c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 10939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin StreamConfigurationDuration[] durations = getDurations(duration); 10959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 10969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (StreamConfigurationDuration configurationDuration : durations) { 10979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (configurationDuration.getFormat() == format && 10989c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin configurationDuration.getWidth() == size.getWidth() && 10999c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin configurationDuration.getHeight() == size.getHeight()) { 11009c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return configurationDuration.getDuration(); 11019c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11029c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1103abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala // Default duration is '0' (unsupported/no extra stall) 1104abd9d3c5c7100c45812ee80975ac59f5b1902a71Eino-Ville Talvala return 0; 11059c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11069c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11079c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 11089c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * Get the durations array for the kind of duration 11099c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * 11109c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #DURATION_MIN_FRAME 11119c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #DURATION_STALL 11129c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * */ 11139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private StreamConfigurationDuration[] getDurations(int duration) { 11149c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin switch (duration) { 11159c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case DURATION_MIN_FRAME: 11169c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return mMinFrameDurations; 11179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin case DURATION_STALL: 11189c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return mStallDurations; 11199c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin default: 11209c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin throw new IllegalArgumentException("duration was invalid"); 11219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11229c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11239c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11249c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** Count the number of publicly-visible output formats */ 11259c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private int getPublicFormatCount(boolean output) { 11269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin HashMap<Integer, Integer> formatsMap = getFormatsMap(output); 11279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin int size = formatsMap.size(); 11299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (formatsMap.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { 11309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin size -= 1; 11319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 1132fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) { 1133fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala size -= 1; 1134fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 1135fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala 11369c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return size; 11379c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static <T> boolean arrayContains(T[] array, T element) { 11409c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (array == null) { 11419c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return false; 11429c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11439c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11449c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin for (T el : array) { 11459c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin if (Objects.equals(el, element)) { 11469c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return true; 11479c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11489c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11499c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11509c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin return false; 11519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin } 11529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin // from system/core/include/system/graphics.h 11549c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final int HAL_PIXEL_FORMAT_BLOB = 0x21; 11559c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22; 11569c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final int HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24; 11579c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11589c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** 11599c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #getDurations(int) 11609c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin * @see #getDurationDefault(int) 11619c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin */ 11629c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final int DURATION_MIN_FRAME = 0; 11639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private static final int DURATION_STALL = 1; 11649c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private final StreamConfiguration[] mConfigurations; 11669c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private final StreamConfigurationDuration[] mMinFrameDurations; 11679c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private final StreamConfigurationDuration[] mStallDurations; 116812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh private final HighSpeedVideoConfiguration[] mHighSpeedVideoConfigurations; 11699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** ImageFormat -> num output sizes mapping */ 11719c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mOutputFormats = 11729c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin new HashMap<Integer, Integer>(); 11739c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin /** ImageFormat -> num input sizes mapping */ 11749c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mInputFormats = 11759c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin new HashMap<Integer, Integer>(); 117612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** High speed video Size -> FPS range count mapping*/ 117712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh private final HashMap</*HighSpeedVideoSize*/Size, /*Count*/Integer> mHighSpeedVideoSizeMap = 117812da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh new HashMap<Size, Integer>(); 117912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh /** High speed video FPS range -> Size count mapping*/ 118012da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh private final HashMap</*HighSpeedVideoFpsRange*/Range<Integer>, /*Count*/Integer> 118112da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh mHighSpeedVideoFpsRangeMap = new HashMap<Range<Integer>, Integer>(); 11829c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin 11839c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin} 1184