am 5e91151d: am 900d0072: am bda40b57: am e3ad6ff8: am c79b145f: Merge "camera2-legacy: Workaround max jpeg/preview size AR mismatch" into lmp-dev
* commit '5e91151d0f88e87055ffdfcd764c71ffa72df37e': camera2-legacy: Workaround max jpeg/preview size AR mismatch
This commit is contained in:
@@ -34,7 +34,6 @@ import android.hardware.camera2.params.StreamConfigurationDuration;
|
||||
import android.hardware.camera2.utils.ArrayUtils;
|
||||
import android.hardware.camera2.utils.ListUtils;
|
||||
import android.hardware.camera2.utils.ParamsUtils;
|
||||
import android.hardware.camera2.utils.SizeAreaComparator;
|
||||
import android.util.Log;
|
||||
import android.util.Range;
|
||||
import android.util.Size;
|
||||
@@ -88,6 +87,9 @@ public class LegacyMetadataMapper {
|
||||
|
||||
static final int UNKNOWN_MODE = -1;
|
||||
|
||||
// Maximum difference between a preview size aspect ratio and a jpeg size aspect ratio
|
||||
private static final float PREVIEW_ASPECT_RATIO_TOLERANCE = 0.01f;
|
||||
|
||||
/*
|
||||
* Development hijinks: Lie about not supporting certain capabilities
|
||||
*
|
||||
@@ -103,6 +105,7 @@ public class LegacyMetadataMapper {
|
||||
static final boolean LIE_ABOUT_AWB_STATE = false;
|
||||
static final boolean LIE_ABOUT_AWB = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create characteristics for a legacy device by mapping the {@code parameters}
|
||||
* and {@code info}
|
||||
@@ -262,6 +265,64 @@ public class LegacyMetadataMapper {
|
||||
* remapping to public format constants.
|
||||
*/
|
||||
List<Camera.Size> previewSizes = p.getSupportedPreviewSizes();
|
||||
List<Camera.Size> jpegSizes = p.getSupportedPictureSizes();
|
||||
/*
|
||||
* Work-around for b/17589233:
|
||||
* - Some HALs's largest preview size aspect ratio does not match the largest JPEG size AR
|
||||
* - This causes a large amount of problems with focus/metering because it's relative to
|
||||
* preview, making the difference between the JPEG and preview viewport inaccessible
|
||||
* - This boils down to metering or focusing areas being "arbitrarily" cropped
|
||||
* in the capture result.
|
||||
* - Work-around the HAL limitations by removing all of the largest preview sizes
|
||||
* until we get one with the same aspect ratio as the jpeg size.
|
||||
*/
|
||||
{
|
||||
SizeAreaComparator areaComparator = new SizeAreaComparator();
|
||||
|
||||
// Sort preview to min->max
|
||||
Collections.sort(previewSizes, areaComparator);
|
||||
|
||||
Camera.Size maxJpegSize = SizeAreaComparator.findLargestByArea(jpegSizes);
|
||||
float jpegAspectRatio = maxJpegSize.width * 1.0f / maxJpegSize.height;
|
||||
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, String.format("mapScalerStreamConfigs - largest JPEG area %dx%d, AR=%f",
|
||||
maxJpegSize.width, maxJpegSize.height, jpegAspectRatio));
|
||||
}
|
||||
|
||||
// Now remove preview sizes from the end (largest->smallest) until aspect ratio matches
|
||||
while (!previewSizes.isEmpty()) {
|
||||
int index = previewSizes.size() - 1; // max is always at the end
|
||||
Camera.Size size = previewSizes.get(index);
|
||||
|
||||
float previewAspectRatio = size.width * 1.0f / size.height;
|
||||
|
||||
if (Math.abs(jpegAspectRatio - previewAspectRatio) >=
|
||||
PREVIEW_ASPECT_RATIO_TOLERANCE) {
|
||||
previewSizes.remove(index); // Assume removing from end is O(1)
|
||||
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, String.format(
|
||||
"mapScalerStreamConfigs - removed preview size %dx%d, AR=%f "
|
||||
+ "was not the same",
|
||||
size.width, size.height, previewAspectRatio));
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (previewSizes.isEmpty()) {
|
||||
// Fall-back to the original faulty behavior, but at least work
|
||||
Log.w(TAG, "mapScalerStreamConfigs - failed to find any preview size matching " +
|
||||
"JPEG aspect ratio " + jpegAspectRatio);
|
||||
previewSizes = p.getSupportedPreviewSizes();
|
||||
}
|
||||
|
||||
// Sort again, this time in descending order max->min
|
||||
Collections.sort(previewSizes, Collections.reverseOrder(areaComparator));
|
||||
}
|
||||
|
||||
appendStreamConfig(availableStreamConfigs,
|
||||
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes);
|
||||
appendStreamConfig(availableStreamConfigs,
|
||||
@@ -279,7 +340,6 @@ public class LegacyMetadataMapper {
|
||||
}
|
||||
}
|
||||
|
||||
List<Camera.Size> jpegSizes = p.getSupportedPictureSizes();
|
||||
appendStreamConfig(availableStreamConfigs,
|
||||
HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes());
|
||||
/*
|
||||
@@ -620,7 +680,7 @@ public class LegacyMetadataMapper {
|
||||
|
||||
if (thumbnailSizes != null) {
|
||||
Size[] sizes = convertSizeListToArray(thumbnailSizes);
|
||||
Arrays.sort(sizes, new SizeAreaComparator());
|
||||
Arrays.sort(sizes, new android.hardware.camera2.utils.SizeAreaComparator());
|
||||
m.set(JPEG_AVAILABLE_THUMBNAIL_SIZES, sizes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.hardware.camera2.legacy;
|
||||
|
||||
import android.hardware.Camera;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.internal.util.Preconditions.*;
|
||||
|
||||
/**
|
||||
* Comparator for api1 {@link Camera.Size} objects by the area.
|
||||
*
|
||||
* <p>This comparator totally orders by rectangle area. Tie-breaks on width.</p>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SizeAreaComparator implements Comparator<Camera.Size> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int compare(Camera.Size size, Camera.Size size2) {
|
||||
checkNotNull(size, "size must not be null");
|
||||
checkNotNull(size2, "size2 must not be null");
|
||||
|
||||
if (size.equals(size2)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long width = size.width;
|
||||
long width2 = size2.width;
|
||||
long area = width * size.height;
|
||||
long area2 = width2 * size2.height;
|
||||
|
||||
if (area == area2) {
|
||||
return (width > width2) ? 1 : -1;
|
||||
}
|
||||
|
||||
return (area > area2) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the largest api1 {@code Camera.Size} from the list by comparing each size's area
|
||||
* by each other using {@link SizeAreaComparator}.
|
||||
*
|
||||
* @param sizes a non-{@code null} list of non-{@code null} sizes
|
||||
* @return a non-{@code null} size
|
||||
*
|
||||
* @throws NullPointerException if {@code sizes} or any elements in it were {@code null}
|
||||
*/
|
||||
public static Camera.Size findLargestByArea(List<Camera.Size> sizes) {
|
||||
checkNotNull(sizes, "sizes must not be null");
|
||||
|
||||
return Collections.max(sizes, new SizeAreaComparator());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user