am f1aea7f9: Merge "camera2: Add jpeg metadata for LEGACY shim." into lmp-dev
* commit 'f1aea7f92498e3f107350c6d1a41e211d1c764a3': camera2: Add jpeg metadata for LEGACY shim.
This commit is contained in:
@@ -510,4 +510,6 @@ public class LegacyCameraDevice implements AutoCloseable {
|
||||
/*out*/int[/*2*/] dimens);
|
||||
|
||||
private static native int nativeSetNextTimestamp(Surface surface, long timestamp);
|
||||
|
||||
static native int nativeGetJpegFooterSize();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ 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;
|
||||
@@ -40,6 +41,8 @@ import android.util.SizeF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.internal.util.Preconditions.*;
|
||||
@@ -187,8 +190,10 @@ public class LegacyMetadataMapper {
|
||||
* flash.*
|
||||
*/
|
||||
mapFlash(m, p);
|
||||
|
||||
// TODO: map other fields
|
||||
/*
|
||||
* jpeg.*
|
||||
*/
|
||||
mapJpeg(m, p);
|
||||
|
||||
/*
|
||||
* scaler.*
|
||||
@@ -595,6 +600,16 @@ public class LegacyMetadataMapper {
|
||||
m.set(FLASH_INFO_AVAILABLE, flashAvailable);
|
||||
}
|
||||
|
||||
private static void mapJpeg(CameraMetadataNative m, Camera.Parameters p) {
|
||||
List<Camera.Size> thumbnailSizes = p.getSupportedJpegThumbnailSizes();
|
||||
|
||||
if (thumbnailSizes != null) {
|
||||
Size[] sizes = convertSizeListToArray(thumbnailSizes);
|
||||
Arrays.sort(sizes, new SizeAreaComparator());
|
||||
m.set(JPEG_AVAILABLE_THUMBNAIL_SIZES, sizes);
|
||||
}
|
||||
}
|
||||
|
||||
private static void mapRequest(CameraMetadataNative m, Parameters p) {
|
||||
/*
|
||||
* request.availableCapabilities
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.hardware.camera2.CaptureRequest;
|
||||
import android.hardware.camera2.params.MeteringRectangle;
|
||||
import android.hardware.camera2.utils.ListUtils;
|
||||
import android.hardware.camera2.utils.ParamsUtils;
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
import android.util.Range;
|
||||
import android.util.Size;
|
||||
@@ -44,6 +45,8 @@ public class LegacyRequestMapper {
|
||||
private static final String TAG = "LegacyRequestMapper";
|
||||
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
|
||||
|
||||
private static final byte DEFAULT_JPEG_QUALITY = 85;
|
||||
|
||||
/**
|
||||
* Set the legacy parameters using the {@link LegacyRequest legacy request}.
|
||||
*
|
||||
@@ -350,6 +353,70 @@ public class LegacyRequestMapper {
|
||||
+ testPatternMode + "; only OFF is supported");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* jpeg.*
|
||||
*/
|
||||
|
||||
// jpeg.gpsLocation
|
||||
{
|
||||
Location location = request.get(JPEG_GPS_LOCATION);
|
||||
if (location != null) {
|
||||
if (checkForCompleteGpsData(location)) {
|
||||
params.setGpsAltitude(location.getAltitude());
|
||||
params.setGpsLatitude(location.getLatitude());
|
||||
params.setGpsLongitude(location.getLongitude());
|
||||
params.setGpsProcessingMethod(location.getProvider().toUpperCase());
|
||||
params.setGpsTimestamp(location.getTime());
|
||||
} else {
|
||||
Log.w(TAG, "Incomplete GPS parameters provided in location " + location);
|
||||
}
|
||||
} else {
|
||||
params.removeGpsData();
|
||||
}
|
||||
}
|
||||
|
||||
// jpeg.orientation
|
||||
{
|
||||
int orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
|
||||
params.setRotation(ParamsUtils.getOrDefault(request, JPEG_ORIENTATION, orientation));
|
||||
}
|
||||
|
||||
// jpeg.quality
|
||||
{
|
||||
params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_QUALITY,
|
||||
DEFAULT_JPEG_QUALITY));
|
||||
}
|
||||
|
||||
// jpeg.thumbnailQuality
|
||||
{
|
||||
params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_THUMBNAIL_QUALITY,
|
||||
DEFAULT_JPEG_QUALITY));
|
||||
}
|
||||
|
||||
// jpeg.thumbnailSize
|
||||
{
|
||||
List<Camera.Size> sizes = params.getSupportedJpegThumbnailSizes();
|
||||
|
||||
if (sizes != null && sizes.size() > 0) {
|
||||
Size s = request.get(JPEG_THUMBNAIL_SIZE);
|
||||
boolean invalidSize = (s == null) ? false : !ParameterUtils.containsSize(sizes,
|
||||
s.getWidth(), s.getHeight());
|
||||
if (invalidSize) {
|
||||
Log.w(TAG, "Invalid JPEG thumbnail size set " + s + ", skipping thumbnail...");
|
||||
}
|
||||
if (s == null || invalidSize) {
|
||||
// (0,0) = "no thumbnail" in Camera API 1
|
||||
params.setJpegThumbnailSize(/*width*/0, /*height*/0);
|
||||
} else {
|
||||
params.setJpegThumbnailSize(s.getWidth(), s.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkForCompleteGpsData(Location location) {
|
||||
return location != null && location.getProvider() != null && location.getTime() != 0;
|
||||
}
|
||||
|
||||
static int filterSupportedCaptureIntent(int captureIntent) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.hardware.camera2.legacy.ParameterUtils.ZoomData;
|
||||
import android.hardware.camera2.params.MeteringRectangle;
|
||||
import android.hardware.camera2.utils.ListUtils;
|
||||
import android.hardware.camera2.utils.ParamsUtils;
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
|
||||
@@ -250,6 +251,29 @@ public class LegacyResultMapper {
|
||||
result.set(SENSOR_TEST_PATTERN_MODE, SENSOR_TEST_PATTERN_MODE_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* jpeg
|
||||
*/
|
||||
// jpeg.gpsLocation
|
||||
result.set(JPEG_GPS_LOCATION, request.get(CaptureRequest.JPEG_GPS_LOCATION));
|
||||
|
||||
// jpeg.orientation
|
||||
result.set(JPEG_ORIENTATION, request.get(CaptureRequest.JPEG_ORIENTATION));
|
||||
|
||||
// jpeg.quality
|
||||
result.set(JPEG_QUALITY, (byte) params.getJpegQuality());
|
||||
|
||||
// jpeg.thumbnailQuality
|
||||
result.set(JPEG_THUMBNAIL_QUALITY, (byte) params.getJpegThumbnailQuality());
|
||||
|
||||
// jpeg.thumbnailSize
|
||||
Camera.Size s = params.getJpegThumbnailSize();
|
||||
if (s != null) {
|
||||
result.set(JPEG_THUMBNAIL_SIZE, ParameterUtils.convertSize(s));
|
||||
} else {
|
||||
Log.w(TAG, "Null thumbnail size received from parameters.");
|
||||
}
|
||||
|
||||
// TODO: Remaining result metadata tags conversions.
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,33 @@ public class ParameterUtils {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a camera API1 list of sizes into an array of sizes
|
||||
*/
|
||||
public static Size[] convertSizeListToArray(List<Camera.Size> sizeList) {
|
||||
checkNotNull(sizeList, "sizeList must not be null");
|
||||
|
||||
Size[] array = new Size[sizeList.size()];
|
||||
int ctr = 0;
|
||||
for (Camera.Size s : sizeList) {
|
||||
array[ctr++] = new Size(s.width, s.height);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the camera API1 list of sizes contains a size with the given dimens.
|
||||
*/
|
||||
public static boolean containsSize(List<Camera.Size> sizeList, int width, int height) {
|
||||
checkNotNull(sizeList, "sizeList must not be null");
|
||||
for (Camera.Size s : sizeList) {
|
||||
if (s.height == height && s.width == width) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest supported picture size, as compared by its area.
|
||||
*/
|
||||
|
||||
@@ -190,7 +190,8 @@ public class RequestThreadManager {
|
||||
try {
|
||||
if (RequestHolder.jpegType(s)) {
|
||||
Log.i(TAG, "Producing jpeg buffer...");
|
||||
LegacyCameraDevice.setSurfaceDimens(s, data.length, /*height*/1);
|
||||
LegacyCameraDevice.setSurfaceDimens(s, data.length +
|
||||
LegacyCameraDevice.nativeGetJpegFooterSize(), /*height*/1);
|
||||
LegacyCameraDevice.setNextTimestamp(s, timestamp);
|
||||
LegacyCameraDevice.produceFrame(s, data, data.length, /*height*/1,
|
||||
CameraMetadataNative.NATIVE_JPEG_FORMAT);
|
||||
@@ -665,10 +666,6 @@ public class RequestThreadManager {
|
||||
}
|
||||
mReceivedJpeg.close();
|
||||
doJpegCapturePrepare(holder);
|
||||
if (!mReceivedJpeg.block(JPEG_FRAME_TIMEOUT)) {
|
||||
// TODO: report error to CameraDevice
|
||||
Log.e(TAG, "Hit timeout for jpeg callback!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -633,6 +633,11 @@ static jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz,
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) {
|
||||
ALOGV("nativeGetJpegFooterSize");
|
||||
return static_cast<jint>(sizeof(struct camera3_jpeg_blob));
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
static JNINativeMethod gCameraDeviceMethods[] = {
|
||||
@@ -666,6 +671,9 @@ static JNINativeMethod gCameraDeviceMethods[] = {
|
||||
{ "nativeSetNextTimestamp",
|
||||
"(Landroid/view/Surface;J)I",
|
||||
(void *)LegacyCameraDevice_nativeSetNextTimestamp },
|
||||
{ "nativeGetJpegFooterSize",
|
||||
"()I",
|
||||
(void *)LegacyCameraDevice_nativeGetJpegFooterSize },
|
||||
};
|
||||
|
||||
// Get all the required offsets in java class and register native functions
|
||||
|
||||
Reference in New Issue
Block a user