summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2014-08-16 00:13:05 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-15 18:45:09 +0000
commite364aecf17124e0ae443bf9fe0e1b7c588a0d25a (patch)
treefa741c38765567353b1856a257fe8a36de9d6538
parenta9bc3559109836efe7479a3279713bd58810b153 (diff)
parent1dc1326eaedd11ffd8f85927b8f0195f4f7598d3 (diff)
downloadframeworks_base-e364aecf17124e0ae443bf9fe0e1b7c588a0d25a.zip
frameworks_base-e364aecf17124e0ae443bf9fe0e1b7c588a0d25a.tar.gz
frameworks_base-e364aecf17124e0ae443bf9fe0e1b7c588a0d25a.tar.bz2
Merge "camera2: Add jpeg metadata for LEGACY shim." into lmp-dev
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java19
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java67
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyResultMapper.java24
-rw-r--r--core/java/android/hardware/camera2/legacy/ParameterUtils.java27
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestThreadManager.java7
-rw-r--r--core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp8
7 files changed, 147 insertions, 7 deletions
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index cbf4a3d..1cf7797 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -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();
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 0337c96..fbe26e5 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -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
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
index 35646fe..4c4ad0d 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
@@ -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) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index a2f9b4c..090a822 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -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;
}
diff --git a/core/java/android/hardware/camera2/legacy/ParameterUtils.java b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
index 385f844..98adcea 100644
--- a/core/java/android/hardware/camera2/legacy/ParameterUtils.java
+++ b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
@@ -253,6 +253,33 @@ public class ParameterUtils {
}
/**
+ * 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.
*/
public static Size getLargestSupportedJpegSizeByArea(Camera.Parameters params) {
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 5c66753..eb8debb 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -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!");
- }
}
/*
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 4cc36aa..980ead0 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -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