Loading core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +11 −8 Original line number Diff line number Diff line Loading @@ -614,14 +614,16 @@ public class LegacyCameraDevice implements AutoCloseable { return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface)); } static void configureSurface(Surface surface, int width, int height, int pixelFormat) throws BufferQueueAbandonedException { static void connectSurface(Surface surface) throws BufferQueueAbandonedException { checkNotNull(surface); checkArgumentPositive(width, "width must be positive."); checkArgumentPositive(height, "height must be positive."); LegacyExceptionUtils.throwOnError(nativeConfigureSurface(surface, width, height, pixelFormat)); LegacyExceptionUtils.throwOnError(nativeConnectSurface(surface)); } static void disconnectSurface(Surface surface) throws BufferQueueAbandonedException { if (surface == null) return; LegacyExceptionUtils.throwOnError(nativeDisconnectSurface(surface)); } static void produceFrame(Surface surface, byte[] pixelBuffer, int width, Loading Loading @@ -716,8 +718,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeDetectSurfaceDimens(Surface surface, /*out*/int[/*2*/] dimens); private static native int nativeConfigureSurface(Surface surface, int width, int height, int pixelFormat); private static native int nativeConnectSurface(Surface surface); private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, int height, int pixelFormat); Loading @@ -740,5 +741,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeSetScalingMode(Surface surface, int scalingMode); private static native int nativeDisconnectSurface(Surface surface); static native int nativeGetJpegFooterSize(); } core/java/android/hardware/camera2/legacy/RequestThreadManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,14 @@ public class RequestThreadManager { mGLThreadManager.waitUntilIdle(); } resetJpegSurfaceFormats(mCallbackOutputs); for (Surface s : mCallbackOutputs) { try { LegacyCameraDevice.disconnectSurface(s); } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { Log.w(TAG, "Surface abandoned, skipping...", e); } } mPreviewOutputs.clear(); mCallbackOutputs.clear(); mJpegSurfaceIds.clear(); Loading Loading @@ -392,6 +400,10 @@ public class RequestThreadManager { mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s)); mCallbackOutputs.add(s); callbackOutputSizes.add(outSize); // LegacyCameraDevice is the producer of JPEG output surfaces // so LegacyCameraDevice needs to connect to the surfaces. LegacyCameraDevice.connectSurface(s); break; default: LegacyCameraDevice.setScalingMode(s, LegacyCameraDevice. Loading core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +10 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,13 @@ public class SurfaceTextureRenderer { private void clearState() { mSurfaces.clear(); for (EGLSurfaceHolder holder : mConversionSurfaces) { try { LegacyCameraDevice.disconnectSurface(holder.surface); } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { Log.w(TAG, "Surface abandoned, skipping...", e); } } mConversionSurfaces.clear(); mPBufferPixels = null; if (mSurfaceTexture != null) { Loading Loading @@ -631,6 +638,9 @@ public class SurfaceTextureRenderer { holder.height = surfaceSize.getHeight(); if (LegacyCameraDevice.needsConversion(s)) { mConversionSurfaces.add(holder); // LegacyCameraDevice is the producer of surfaces if it's not handled by EGL, // so LegacyCameraDevice needs to connect to the surfaces. LegacyCameraDevice.connectSurface(s); } else { mSurfaces.add(holder); } Loading core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +43 −32 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <gui/Surface.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IProducerListener.h> #include <ui/GraphicBuffer.h> #include <system/window.h> #include <hardware/camera3.h> Loading Loading @@ -93,27 +94,17 @@ static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_yc cStep, yStride, cStride); } static status_t configureSurface(const sp<ANativeWindow>& anw, int32_t width, int32_t height, int32_t pixelFmt, int32_t maxBufferSlack) { static status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) { status_t err = NO_ERROR; err = native_window_set_buffers_dimensions(anw.get(), width, height); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } err = native_window_set_buffers_format(anw.get(), pixelFmt); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL); if (err != OK) { ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, strerror(-err), err); Loading @@ -121,19 +112,17 @@ static status_t configureSurface(const sp<ANativeWindow>& anw, } int minUndequeuedBuffers; err = anw.get()->query(anw.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, maxBufferSlack + 1 + minUndequeuedBuffers, width, height, pixelFmt); err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); ALOGV("%s: Setting buffer count to %d", __FUNCTION__, maxBufferSlack + 1 + minUndequeuedBuffers); err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, strerror(-err), err); Loading Loading @@ -509,6 +498,26 @@ static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobjec return usage; } static jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz, jobject surface) { ALOGV("nativeDisconnectSurface"); if (surface == nullptr) return NO_ERROR; sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGV("Buffer queue has already been abandoned."); return NO_ERROR; } status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA); if(err != NO_ERROR) { jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", "Error while disconnecting surface"); return err; } return NO_ERROR; } static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, jobject surfaceTexture, jintArray dimens) { ALOGV("nativeDetectTextureDimens"); Loading Loading @@ -540,15 +549,14 @@ static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject th return NO_ERROR; } static jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, jint width, jint height, jint pixelFormat) { ALOGV("nativeConfigureSurface"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); static jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) { ALOGV("nativeConnectSurface"); sp<Surface> s; if ((s = getSurface(env, surface)) == NULL) { ALOGE("%s: Could not retrieve surface.", __FUNCTION__); return BAD_VALUE; } status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK); if (err != NO_ERROR) { ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); return err; Loading Loading @@ -740,9 +748,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeDetectSurfaceDimens", "(Landroid/view/Surface;[I)I", (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, { "nativeConfigureSurface", "(Landroid/view/Surface;III)I", (void *)LegacyCameraDevice_nativeConfigureSurface }, { "nativeConnectSurface", "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeConnectSurface }, { "nativeProduceFrame", "(Landroid/view/Surface;[BIII)I", (void *)LegacyCameraDevice_nativeProduceFrame }, Loading Loading @@ -773,6 +781,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeSetScalingMode", "(Landroid/view/Surface;I)I", (void *)LegacyCameraDevice_nativeSetScalingMode }, { "nativeDisconnectSurface", "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeDisconnectSurface }, }; // Get all the required offsets in java class and register native functions Loading Loading
core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +11 −8 Original line number Diff line number Diff line Loading @@ -614,14 +614,16 @@ public class LegacyCameraDevice implements AutoCloseable { return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface)); } static void configureSurface(Surface surface, int width, int height, int pixelFormat) throws BufferQueueAbandonedException { static void connectSurface(Surface surface) throws BufferQueueAbandonedException { checkNotNull(surface); checkArgumentPositive(width, "width must be positive."); checkArgumentPositive(height, "height must be positive."); LegacyExceptionUtils.throwOnError(nativeConfigureSurface(surface, width, height, pixelFormat)); LegacyExceptionUtils.throwOnError(nativeConnectSurface(surface)); } static void disconnectSurface(Surface surface) throws BufferQueueAbandonedException { if (surface == null) return; LegacyExceptionUtils.throwOnError(nativeDisconnectSurface(surface)); } static void produceFrame(Surface surface, byte[] pixelBuffer, int width, Loading Loading @@ -716,8 +718,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeDetectSurfaceDimens(Surface surface, /*out*/int[/*2*/] dimens); private static native int nativeConfigureSurface(Surface surface, int width, int height, int pixelFormat); private static native int nativeConnectSurface(Surface surface); private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, int height, int pixelFormat); Loading @@ -740,5 +741,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeSetScalingMode(Surface surface, int scalingMode); private static native int nativeDisconnectSurface(Surface surface); static native int nativeGetJpegFooterSize(); }
core/java/android/hardware/camera2/legacy/RequestThreadManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,14 @@ public class RequestThreadManager { mGLThreadManager.waitUntilIdle(); } resetJpegSurfaceFormats(mCallbackOutputs); for (Surface s : mCallbackOutputs) { try { LegacyCameraDevice.disconnectSurface(s); } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { Log.w(TAG, "Surface abandoned, skipping...", e); } } mPreviewOutputs.clear(); mCallbackOutputs.clear(); mJpegSurfaceIds.clear(); Loading Loading @@ -392,6 +400,10 @@ public class RequestThreadManager { mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s)); mCallbackOutputs.add(s); callbackOutputSizes.add(outSize); // LegacyCameraDevice is the producer of JPEG output surfaces // so LegacyCameraDevice needs to connect to the surfaces. LegacyCameraDevice.connectSurface(s); break; default: LegacyCameraDevice.setScalingMode(s, LegacyCameraDevice. Loading
core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +10 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,13 @@ public class SurfaceTextureRenderer { private void clearState() { mSurfaces.clear(); for (EGLSurfaceHolder holder : mConversionSurfaces) { try { LegacyCameraDevice.disconnectSurface(holder.surface); } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { Log.w(TAG, "Surface abandoned, skipping...", e); } } mConversionSurfaces.clear(); mPBufferPixels = null; if (mSurfaceTexture != null) { Loading Loading @@ -631,6 +638,9 @@ public class SurfaceTextureRenderer { holder.height = surfaceSize.getHeight(); if (LegacyCameraDevice.needsConversion(s)) { mConversionSurfaces.add(holder); // LegacyCameraDevice is the producer of surfaces if it's not handled by EGL, // so LegacyCameraDevice needs to connect to the surfaces. LegacyCameraDevice.connectSurface(s); } else { mSurfaces.add(holder); } Loading
core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +43 −32 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <gui/Surface.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IProducerListener.h> #include <ui/GraphicBuffer.h> #include <system/window.h> #include <hardware/camera3.h> Loading Loading @@ -93,27 +94,17 @@ static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_yc cStep, yStride, cStride); } static status_t configureSurface(const sp<ANativeWindow>& anw, int32_t width, int32_t height, int32_t pixelFmt, int32_t maxBufferSlack) { static status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) { status_t err = NO_ERROR; err = native_window_set_buffers_dimensions(anw.get(), width, height); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } err = native_window_set_buffers_format(anw.get(), pixelFmt); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL); if (err != OK) { ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, strerror(-err), err); Loading @@ -121,19 +112,17 @@ static status_t configureSurface(const sp<ANativeWindow>& anw, } int minUndequeuedBuffers; err = anw.get()->query(anw.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, maxBufferSlack + 1 + minUndequeuedBuffers, width, height, pixelFmt); err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); ALOGV("%s: Setting buffer count to %d", __FUNCTION__, maxBufferSlack + 1 + minUndequeuedBuffers); err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, strerror(-err), err); Loading Loading @@ -509,6 +498,26 @@ static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobjec return usage; } static jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz, jobject surface) { ALOGV("nativeDisconnectSurface"); if (surface == nullptr) return NO_ERROR; sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGV("Buffer queue has already been abandoned."); return NO_ERROR; } status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA); if(err != NO_ERROR) { jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", "Error while disconnecting surface"); return err; } return NO_ERROR; } static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, jobject surfaceTexture, jintArray dimens) { ALOGV("nativeDetectTextureDimens"); Loading Loading @@ -540,15 +549,14 @@ static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject th return NO_ERROR; } static jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, jint width, jint height, jint pixelFormat) { ALOGV("nativeConfigureSurface"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); static jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) { ALOGV("nativeConnectSurface"); sp<Surface> s; if ((s = getSurface(env, surface)) == NULL) { ALOGE("%s: Could not retrieve surface.", __FUNCTION__); return BAD_VALUE; } status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK); if (err != NO_ERROR) { ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); return err; Loading Loading @@ -740,9 +748,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeDetectSurfaceDimens", "(Landroid/view/Surface;[I)I", (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, { "nativeConfigureSurface", "(Landroid/view/Surface;III)I", (void *)LegacyCameraDevice_nativeConfigureSurface }, { "nativeConnectSurface", "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeConnectSurface }, { "nativeProduceFrame", "(Landroid/view/Surface;[BIII)I", (void *)LegacyCameraDevice_nativeProduceFrame }, Loading Loading @@ -773,6 +781,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeSetScalingMode", "(Landroid/view/Surface;I)I", (void *)LegacyCameraDevice_nativeSetScalingMode }, { "nativeDisconnectSurface", "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeDisconnectSurface }, }; // Get all the required offsets in java class and register native functions Loading