summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java33
-rw-r--r--core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java7
-rw-r--r--core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp71
3 files changed, 97 insertions, 14 deletions
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 4b39092..79f4403 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -33,6 +33,7 @@ import android.util.Size;
import android.view.Surface;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import static android.hardware.camera2.legacy.LegacyExceptionUtils.*;
@@ -271,6 +272,9 @@ public class LegacyCameraDevice implements AutoCloseable {
return BAD_VALUE;
}
+ List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
+ getSurfaceIds(mConfiguredSurfaces);
+
// Make sure that there all requests have at least 1 surface; all surfaces are non-null
for (CaptureRequest request : requestList) {
if (request.getTargets().isEmpty()) {
@@ -287,7 +291,7 @@ public class LegacyCameraDevice implements AutoCloseable {
Log.e(TAG, "submitRequestList - must configure " +
" device with valid surfaces before submitting requests");
return INVALID_OPERATION;
- } else if (!mConfiguredSurfaces.contains(surface)) {
+ } else if (!containsSurfaceId(surface, surfaceIds)) {
Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured");
return BAD_VALUE;
}
@@ -430,6 +434,32 @@ public class LegacyCameraDevice implements AutoCloseable {
LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height));
}
+ static long getSurfaceId(Surface surface) {
+ checkNotNull(surface);
+ return nativeGetSurfaceId(surface);
+ }
+
+ static List<Long> getSurfaceIds(Collection<Surface> surfaces) {
+ if (surfaces == null) {
+ throw new NullPointerException("Null argument surfaces");
+ }
+ List<Long> surfaceIds = new ArrayList<>();
+ for (Surface s : surfaces) {
+ long id = getSurfaceId(s);
+ if (id == 0) {
+ throw new IllegalStateException(
+ "Configured surface had null native GraphicBufferProducer pointer!");
+ }
+ surfaceIds.add(id);
+ }
+ return surfaceIds;
+ }
+
+ static boolean containsSurfaceId(Surface s, List<Long> ids) {
+ long id = getSurfaceId(s);
+ return ids.contains(id);
+ }
+
private static native int nativeDetectSurfaceType(Surface surface);
private static native int nativeDetectSurfaceDimens(Surface surface,
@@ -445,4 +475,5 @@ public class LegacyCameraDevice implements AutoCloseable {
private static native int nativeSetSurfaceDimens(Surface surface, int width, int height);
+ private static native long nativeGetSurfaceId(Surface surface);
}
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index e38624a..9969fd2 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -492,19 +492,20 @@ public class SurfaceTextureRenderer {
&& (mConversionSurfaces == null || mConversionSurfaces.size() == 0)) {
return;
}
+
checkGlError("before updateTexImage");
mSurfaceTexture.updateTexImage();
if (targetSurfaces == null) return;
+ List<Long> targetSurfaceIds = LegacyCameraDevice.getSurfaceIds(targetSurfaces);
for (EGLSurfaceHolder holder : mSurfaces) {
- if (targetSurfaces.contains(holder.surface)) {
+ if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
makeCurrent(holder.eglSurface);
drawFrame(mSurfaceTexture);
swapBuffers(holder.eglSurface);
}
-
}
for (EGLSurfaceHolder holder : mConversionSurfaces) {
- if (targetSurfaces.contains(holder.surface)) {
+ if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
makeCurrent(holder.eglSurface);
drawFrame(mSurfaceTexture);
mPBufferPixels.clear();
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 2f24a69..9621bb2 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -25,10 +25,15 @@
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/android_view_Surface.h"
+#include <gui/Surface.h>
+#include <gui/IGraphicBufferProducer.h>
#include <ui/GraphicBuffer.h>
#include <system/window.h>
#include <hardware/camera3.h>
+#include <stdint.h>
+#include <inttypes.h>
+
using namespace android;
// fully-qualified class name
@@ -192,8 +197,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
switch(pixelFmt) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__,
- bufSize);
+ ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ __FUNCTION__, bufSize);
return BAD_VALUE;
}
uint8_t* img = NULL;
@@ -214,8 +219,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
}
case HAL_PIXEL_FORMAT_YV12: {
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__,
- bufSize);
+ ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ __FUNCTION__, bufSize);
return BAD_VALUE;
}
@@ -251,8 +256,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
// Software writes with YCbCr_420_888 format are unsupported
// by the gralloc module for now
if (bufSize < width * height * 4) {
- ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__,
- bufSize);
+ ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions",
+ __FUNCTION__, bufSize);
return BAD_VALUE;
}
android_ycbcr ycbcr = android_ycbcr();
@@ -269,7 +274,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw,
}
case HAL_PIXEL_FORMAT_BLOB: {
if (bufSize != width || height != 1) {
- ALOGE("%s: Incorrect pixelBuffer size: %lld", __FUNCTION__, bufSize);
+ ALOGE("%s: Incorrect pixelBuffer size: %" PRId32, __FUNCTION__, bufSize);
return BAD_VALUE;
}
int8_t* img = NULL;
@@ -316,20 +321,39 @@ static sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) {
if (surface) {
anw = android_view_Surface_getNativeWindow(env, surface);
if (env->ExceptionCheck()) {
- return anw;
+ return NULL;
}
} else {
jniThrowNullPointerException(env, "surface");
- return anw;
+ return NULL;
}
if (anw == NULL) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"Surface had no valid native window.");
- return anw;
+ return NULL;
}
return anw;
}
+static sp<Surface> getSurface(JNIEnv* env, jobject surface) {
+ sp<Surface> s;
+ if (surface) {
+ s = android_view_Surface_getSurface(env, surface);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+ } else {
+ jniThrowNullPointerException(env, "surface");
+ return NULL;
+ }
+ if (s == NULL) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "Surface had no valid native Surface.");
+ return NULL;
+ }
+ return s;
+}
+
extern "C" {
static jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) {
@@ -456,6 +480,30 @@ static jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz,
return NO_ERROR;
}
+static jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) {
+ ALOGV("nativeGetSurfaceId");
+ sp<Surface> s;
+ if ((s = getSurface(env, surface)) == NULL) {
+ ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__);
+ return 0;
+ }
+ sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer();
+ if (gbp == NULL) {
+ ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__);
+ return 0;
+ }
+ sp<IBinder> b = gbp->asBinder();
+ if (b == NULL) {
+ ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__);
+ return 0;
+ }
+ /*
+ * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera
+ * service (CameraDeviceClient.h).
+ */
+ return reinterpret_cast<jlong>(b.get());
+}
+
} // extern "C"
static JNINativeMethod gCameraDeviceMethods[] = {
@@ -477,6 +525,9 @@ static JNINativeMethod gCameraDeviceMethods[] = {
{ "nativeSetSurfaceDimens",
"(Landroid/view/Surface;II)I",
(void *)LegacyCameraDevice_nativeSetSurfaceDimens },
+ { "nativeGetSurfaceId",
+ "(Landroid/view/Surface;)J",
+ (void *)LegacyCameraDevice_nativeGetSurfaceId },
};
// Get all the required offsets in java class and register native functions