LegacyCameraDevice.java revision 29c3630563452c9635f0510d071839c112d3017d
1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpackage android.hardware.camera2.legacy; 18feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.graphics.ImageFormat; 2028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkimport android.graphics.SurfaceTexture; 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.Camera; 22df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.camera2.CameraCharacteristics; 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CaptureRequest; 2451dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkinimport android.hardware.camera2.impl.CameraDeviceImpl; 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.impl.CaptureResultExtras; 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceCallbacks; 27e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunkimport android.hardware.camera2.params.StreamConfigurationMap; 28e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunkimport android.hardware.camera2.utils.ArrayUtils; 294aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunkimport android.hardware.camera2.utils.CameraBinderDecorator; 30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.LongParcelable; 31feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.impl.CameraMetadataNative; 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraRuntimeException; 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.ConditionVariable; 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.Handler; 35feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.HandlerThread; 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.RemoteException; 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log; 38f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkimport android.util.Pair; 39a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.util.Size; 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.view.Surface; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.ArrayList; 43e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunkimport java.util.Arrays; 443c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkimport java.util.Collection; 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.List; 4649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 47ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkimport static android.hardware.camera2.legacy.LegacyExceptionUtils.*; 4849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkinimport static android.hardware.camera2.utils.CameraBinderDecorator.*; 49a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport static com.android.internal.util.Preconditions.*; 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This class emulates the functionality of a Camera2 device using a the old Camera class. 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * There are two main components that are used to implement this: 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * - A state machine containing valid Camera2 device states ({@link CameraDeviceState}). 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * - A message-queue based pipeline that manages an old Camera class, and executes capture and 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * configuration requests. 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class LegacyCameraDevice implements AutoCloseable { 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final String TAG; 63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 64a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala private static final boolean DEBUG = false; 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final int mCameraId; 66e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk private final CameraCharacteristics mStaticCharacteristics; 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final ICameraDeviceCallbacks mDeviceCallbacks; 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final CameraDeviceState mDeviceState = new CameraDeviceState(); 6949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin private List<Surface> mConfiguredSurfaces; 70e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk private boolean mClosed = false; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final ConditionVariable mIdle = new ConditionVariable(/*open*/true); 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 74d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk private final HandlerThread mResultThread = new HandlerThread("ResultThread"); 75d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk private final HandlerThread mCallbackHandlerThread = new HandlerThread("CallbackThread"); 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final Handler mCallbackHandler; 77d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk private final Handler mResultHandler; 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int ILLEGAL_VALUE = -1; 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 80f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // Keep up to date with values in hardware/libhardware/include/hardware/gralloc.h 81f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static final int GRALLOC_USAGE_RENDERSCRIPT = 0x00100000; 82f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static final int GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003; 83f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static final int GRALLOC_USAGE_HW_TEXTURE = 0x00000100; 84f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static final int GRALLOC_USAGE_HW_COMPOSER = 0x00000800; 85a7677722304670dc07feef242156b97e6bb51bcdZhijun He private static final int GRALLOC_USAGE_HW_RENDER = 0x00000200; 86f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000; 87f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 8868e4fc8ca9b923bc6d053589329eab8509d625abRuben Brunk public static final int MAX_DIMEN_FOR_ROUNDING = 1920; // maximum allowed width for rounding 89f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 90a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk // Keep up to date with values in system/core/include/system/window.h 91a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk public static final int NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1; 92a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) { 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (holder == null) { 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, 9683159151f618c79040a2e800de8cc78f22bf760bZhijun He ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE); 97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(), 9983159151f618c79040a2e800de8cc78f22bf760bZhijun He /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(), 10083159151f618c79040a2e800de8cc78f22bf760bZhijun He /*partialResultCount*/1); 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Listener for the camera device state machine. Calls the appropriate 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link ICameraDeviceCallbacks} for each state transition. 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final CameraDeviceState.CameraDeviceStateListener mStateListener = 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk new CameraDeviceState.CameraDeviceStateListener() { 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 110e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public void onError(final int errorCode, final RequestHolder holder) { 11151dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin if (DEBUG) { 11251dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin Log.d(TAG, "onError called, errorCode = " + errorCode); 11351dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 11451dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin switch (errorCode) { 11551dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin /* 11651dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin * Only be considered idle if we hit a fatal error 11751dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin * and no further requests can be processed. 11851dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin */ 11951dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DISCONNECTED: 12051dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_SERVICE: 12151dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE: { 12251dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin mIdle.open(); 12351dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin 12451dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin if (DEBUG) { 12551dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin Log.d(TAG, "onError - opening idle"); 12651dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 12751dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 12851dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 12951dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk final CaptureResultExtras extras = getExtrasFromRequest(holder); 131d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultHandler.post(new Runnable() { 132d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk @Override 133d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk public void run() { 1343e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk if (DEBUG) { 135e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.d(TAG, "doing onError callback for request " + holder.getRequestId() + 136e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk ", with error code " + errorCode); 1373e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk } 138d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 139acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mDeviceCallbacks.onDeviceError(errorCode, extras); 140d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (RemoteException e) { 141d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk throw new IllegalStateException( 142d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk "Received remote exception during onCameraError callback: ", e); 143d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 144d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 145d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk }); 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void onConfiguring() { 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Do nothing 1513e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk if (DEBUG) { 1523e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk Log.d(TAG, "doing onConfiguring callback."); 1533e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk } 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void onIdle() { 15851dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin if (DEBUG) { 15951dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin Log.d(TAG, "onIdle called"); 16051dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 16151dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin 162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mIdle.open(); 163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 164d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultHandler.post(new Runnable() { 165d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk @Override 166d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk public void run() { 1673e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk if (DEBUG) { 1683e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk Log.d(TAG, "doing onIdle callback."); 1693e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk } 170d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 171acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mDeviceCallbacks.onDeviceIdle(); 172d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (RemoteException e) { 173d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk throw new IllegalStateException( 174d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk "Received remote exception during onCameraIdle callback: ", e); 175d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 176d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 177d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk }); 178feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 179feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 180feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 18151dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin public void onBusy() { 18251dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin mIdle.close(); 18351dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin 18451dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin if (DEBUG) { 18551dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin Log.d(TAG, "onBusy called"); 18651dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 18751dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin } 18851dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin 18951dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin @Override 190e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public void onCaptureStarted(final RequestHolder holder, final long timestamp) { 191feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk final CaptureResultExtras extras = getExtrasFromRequest(holder); 192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 193d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultHandler.post(new Runnable() { 194d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk @Override 195d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk public void run() { 1963e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk if (DEBUG) { 197e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.d(TAG, "doing onCaptureStarted callback for request " + 198e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk holder.getRequestId()); 1993e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk } 200d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 201d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mDeviceCallbacks.onCaptureStarted(extras, timestamp); 202d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (RemoteException e) { 203d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk throw new IllegalStateException( 204d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk "Received remote exception during onCameraError callback: ", e); 205d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 206d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 207d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk }); 208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 209feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 210feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 211e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public void onCaptureResult(final CameraMetadataNative result, final RequestHolder holder) { 212feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk final CaptureResultExtras extras = getExtrasFromRequest(holder); 213feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 214d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultHandler.post(new Runnable() { 215d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk @Override 216d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk public void run() { 2173e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk if (DEBUG) { 218e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.d(TAG, "doing onCaptureResult callback for request " + 219e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk holder.getRequestId()); 2203e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk } 221d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 222d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mDeviceCallbacks.onResultReceived(result, extras); 223d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (RemoteException e) { 224d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk throw new IllegalStateException( 225d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk "Received remote exception during onCameraError callback: ", e); 226d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 227d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 228d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk }); 229feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 230feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk }; 231feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 232feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final RequestThreadManager mRequestThreadManager; 233feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 234feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 23591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk * Check if a given surface uses {@link ImageFormat#YUV_420_888} or format that can be readily 23691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk * converted to this; YV12 and NV21 are the two currently supported formats. 237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 238feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param s the surface to check. 23991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk * @return {@code true} if the surfaces uses {@link ImageFormat#YUV_420_888} or a compatible 24091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk * format. 241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 242ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk static boolean needsConversion(Surface s) throws BufferQueueAbandonedException { 243ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk int nativeType = detectSurfaceType(s); 24491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return nativeType == ImageFormat.YUV_420_888 || nativeType == ImageFormat.YV12 || 24591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk nativeType == ImageFormat.NV21; 246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 249feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Create a new emulated camera device from a given Camera 1 API camera. 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * The {@link Camera} provided to this constructor must already have been successfully opened, 253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * and ownership of the provided camera is passed to this object. No further calls to the 254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * camera methods should be made following this constructor. 255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param cameraId the id of the camera. 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param camera an open {@link Camera} device. 259df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * @param characteristics the static camera characteristics for this camera device 260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param callbacks {@link ICameraDeviceCallbacks} callbacks to call for Camera2 API operations. 261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 262df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin public LegacyCameraDevice(int cameraId, Camera camera, CameraCharacteristics characteristics, 263df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin ICameraDeviceCallbacks callbacks) { 264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCameraId = cameraId; 265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mDeviceCallbacks = callbacks; 266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk TAG = String.format("CameraDevice-%d-LE", mCameraId); 267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 268d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultThread.start(); 269d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultHandler = new Handler(mResultThread.getLooper()); 270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCallbackHandlerThread.start(); 271feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCallbackHandler = new Handler(mCallbackHandlerThread.getLooper()); 272feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mDeviceState.setCameraDeviceCallbacks(mCallbackHandler, mStateListener); 273e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk mStaticCharacteristics = characteristics; 274feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRequestThreadManager = 275df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin new RequestThreadManager(cameraId, camera, characteristics, mDeviceState); 276feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRequestThreadManager.start(); 277feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 278feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 279feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 280feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Configure the device with a set of output surfaces. 281feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 28249b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin * <p>Using empty or {@code null} {@code outputs} is the same as unconfiguring.</p> 28349b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin * 28449b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin * <p>Every surface in {@code outputs} must be non-{@code null}.</p> 28549b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin * 286feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param outputs a list of surfaces to set. 28749b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin * @return an error code for this binder operation, or {@link NO_ERROR} 288feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * on success. 289feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 290feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int configureOutputs(List<Surface> outputs) { 291f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk List<Pair<Surface, Size>> sizedSurfaces = new ArrayList<>(); 29249b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin if (outputs != null) { 29349b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin for (Surface output : outputs) { 29449b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin if (output == null) { 29549b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "configureOutputs - null outputs are not allowed"); 29649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return BAD_VALUE; 29749b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 298443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk if (!output.isValid()) { 299443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk Log.e(TAG, "configureOutputs - invalid output surfaces are not allowed"); 300443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk return BAD_VALUE; 301443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk } 302e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk StreamConfigurationMap streamConfigurations = mStaticCharacteristics. 303e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 304e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 305e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk // Validate surface size and format. 306e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk try { 307e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Size s = getSurfaceSize(output); 308e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk int surfaceType = detectSurfaceType(output); 309e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 310fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala boolean flexibleConsumer = isFlexibleConsumer(output); 311f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 312f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk Size[] sizes = streamConfigurations.getOutputSizes(surfaceType); 313e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (sizes == null) { 314e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk // WAR: Override default format to IMPLEMENTATION_DEFINED for b/9487482 315e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if ((surfaceType >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 && 316e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk surfaceType <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) { 317e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 318f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // YUV_420_888 is always present in LEGACY for all 319f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // IMPLEMENTATION_DEFINED output sizes, and is publicly visible in the 320f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // API (i.e. {@code #getOutputSizes} works here). 321e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk sizes = streamConfigurations.getOutputSizes(ImageFormat.YUV_420_888); 322e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } else if (surfaceType == LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB) { 323e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk sizes = streamConfigurations.getOutputSizes(ImageFormat.JPEG); 324e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 325e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 326e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 327e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (!ArrayUtils.contains(sizes, s)) { 328f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (flexibleConsumer && (s = findClosestSize(s, sizes)) != null) { 329f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk sizedSurfaces.add(new Pair<>(output, s)); 330f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } else { 331f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk String reason = (sizes == null) ? "format is invalid." : 332f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ("size not in valid set: " + Arrays.toString(sizes)); 333f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format " + 334f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "0x%x is not valid, %s", s.getWidth(), s.getHeight(), 335f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk surfaceType, reason)); 336f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return BAD_VALUE; 337f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 338f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } else { 339f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk sizedSurfaces.add(new Pair<>(output, s)); 340e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 341315bc0971539f97aaf424c6b21b789a7c8ca9e04Eino-Ville Talvala // Lock down the size before configuration 342315bc0971539f97aaf424c6b21b789a7c8ca9e04Eino-Ville Talvala setSurfaceDimens(output, s.getWidth(), s.getHeight()); 343e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } catch (BufferQueueAbandonedException e) { 344e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Surface bufferqueue is abandoned, cannot configure as output: ", e); 345e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return BAD_VALUE; 346e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 347e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 34849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 34949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 35049b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 3514aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk boolean success = false; 3524aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk if (mDeviceState.setConfiguring()) { 353f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk mRequestThreadManager.configure(sizedSurfaces); 3544aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk success = mDeviceState.setIdle(); 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 35649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 3574aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk if (success) { 35849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null; 3594aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } else { 3604aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk return CameraBinderDecorator.INVALID_OPERATION; 36149b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 3624aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk return CameraBinderDecorator.NO_ERROR; 363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 365feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Submit a burst of capture requests. 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param requestList a list of capture requests to execute. 369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param repeating {@code true} if this burst is repeating. 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param frameNumber an output argument that contains either the frame number of the last frame 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * that will be returned for this request, or the frame number of the last 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * frame that will be returned for the current repeating request if this 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * burst is set to be repeating. 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return the request id. 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequestList(List<CaptureRequest> requestList, boolean repeating, 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable frameNumber) { 37849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin if (requestList == null || requestList.isEmpty()) { 37949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "submitRequestList - Empty/null requests are not allowed"); 38049b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return BAD_VALUE; 38149b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 38249b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 3833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() : 3843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk getSurfaceIds(mConfiguredSurfaces); 3853c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 38649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin // Make sure that there all requests have at least 1 surface; all surfaces are non-null 38749b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin for (CaptureRequest request : requestList) { 38849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin if (request.getTargets().isEmpty()) { 38949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "submitRequestList - " 39049b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin + "Each request must have at least one Surface target"); 39149b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return BAD_VALUE; 39249b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 39349b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 39449b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin for (Surface surface : request.getTargets()) { 39549b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin if (surface == null) { 39649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "submitRequestList - Null Surface targets are not allowed"); 39749b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return BAD_VALUE; 39849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } else if (mConfiguredSurfaces == null) { 39949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "submitRequestList - must configure " + 40049b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin " device with valid surfaces before submitting requests"); 40149b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return INVALID_OPERATION; 4023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } else if (!containsSurfaceId(surface, surfaceIds)) { 40349b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured"); 40449b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin return BAD_VALUE; 40549b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 40649b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 40749b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin } 40849b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin 40949b2b135105e5ca5dc9547f4c6de473bebad647dIgor Murashkin // TODO: further validation of request here 410feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mIdle.close(); 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mRequestThreadManager.submitCaptureRequests(requestList, repeating, 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk frameNumber); 413feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 416feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Submit a single capture request. 417feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 418feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param request the capture request to execute. 419feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param repeating {@code true} if this request is repeating. 420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param frameNumber an output argument that contains either the frame number of the last frame 421feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * that will be returned for this request, or the frame number of the last 422feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * frame that will be returned for the current repeating request if this 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * request is set to be repeating. 424feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return the request id. 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequest(CaptureRequest request, boolean repeating, 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable frameNumber) { 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ArrayList<CaptureRequest> requestList = new ArrayList<CaptureRequest>(); 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk requestList.add(request); 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return submitRequestList(requestList, repeating, frameNumber); 431feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Cancel the repeating request with the given request id. 435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param requestId the request id of the request to cancel. 437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return the last frame number to be returned from the HAL for the given repeating request, or 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@code INVALID_FRAME} if none exists. 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 440feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public long cancelRequest(int requestId) { 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mRequestThreadManager.cancelRepeating(requestId); 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 443feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Block until the {@link ICameraDeviceCallbacks#onCameraIdle()} callback is received. 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void waitUntilIdle() { 448feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mIdle.block(); 449feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 450feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 451e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk /** 452e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * Flush any pending requests. 453e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * 454e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * @return the last frame number. 455e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk */ 456e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public long flush() { 457e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk long lastFrame = mRequestThreadManager.flush(); 458e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk waitUntilIdle(); 459e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return lastFrame; 460e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 461e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 462e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk /** 463e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * Return {@code true} if the device has been closed. 464e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk */ 465e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public boolean isClosed() { 466e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return mClosed; 467e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 468e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 469feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void close() { 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRequestThreadManager.quit(); 472feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCallbackHandlerThread.quitSafely(); 473d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultThread.quitSafely(); 474d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk 475d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 476d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mCallbackHandlerThread.join(); 477d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (InterruptedException e) { 478d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.", 479d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mCallbackHandlerThread.getName(), mCallbackHandlerThread.getId())); 480d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 481d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk 482d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 483d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultThread.join(); 484d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (InterruptedException e) { 485d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.", 486d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mResultThread.getName(), mResultThread.getId())); 487d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 488d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk 489e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk mClosed = true; 490feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk protected void finalize() throws Throwable { 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk try { 495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk close(); 496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } catch (CameraRuntimeException e) { 497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Got error while trying to finalize, ignoring: " + e.getMessage()); 498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } finally { 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk super.finalize(); 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 502feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 503f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk static long findEuclidDistSquare(Size a, Size b) { 504f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk long d0 = a.getWidth() - b.getWidth(); 505f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk long d1 = a.getHeight() - b.getHeight(); 506f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return d0 * d0 + d1 * d1; 507f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 508f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 509f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // Keep up to date with rounding behavior in 510f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp 511f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk static Size findClosestSize(Size size, Size[] supportedSizes) { 512f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (size == null || supportedSizes == null) { 513f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return null; 514f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 515f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk Size bestSize = null; 516f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk for (Size s : supportedSizes) { 517f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (s.equals(size)) { 518f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return size; 519f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } else if (s.getWidth() <= MAX_DIMEN_FOR_ROUNDING && (bestSize == null || 520f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk LegacyCameraDevice.findEuclidDistSquare(size, s) < 521f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk LegacyCameraDevice.findEuclidDistSquare(bestSize, s))) { 522f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk bestSize = s; 523f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 524f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 525f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return bestSize; 526f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 527f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 528a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 529a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Query the surface for its currently configured default buffer size. 530a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param surface a non-{@code null} {@code Surface} 531a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @return the width and height of the surface 532a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 533a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @throws NullPointerException if the {@code surface} was {@code null} 534443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk * @throws BufferQueueAbandonedException if the {@code surface} was invalid 535a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 536fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala public static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException { 537a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin checkNotNull(surface); 538a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 539a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin int[] dimens = new int[2]; 540ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDimens(surface, /*out*/dimens)); 541a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 542a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return new Size(dimens[0], dimens[1]); 543a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 544a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 545fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala public static boolean isFlexibleConsumer(Surface output) { 546fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala int usageFlags = detectSurfaceUsageFlags(output); 547fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala 548fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // Keep up to date with allowed consumer types in 549fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp 550fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT; 551fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN | 552fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala GRALLOC_USAGE_HW_COMPOSER; 553fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 && 554fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala (usageFlags & allowedFlags) != 0); 555fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala return flexibleConsumer; 556fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala } 557fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala 558a7677722304670dc07feef242156b97e6bb51bcdZhijun He public static boolean isPreviewConsumer(Surface output) { 559a7677722304670dc07feef242156b97e6bb51bcdZhijun He int usageFlags = detectSurfaceUsageFlags(output); 560a7677722304670dc07feef242156b97e6bb51bcdZhijun He int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT | 561a7677722304670dc07feef242156b97e6bb51bcdZhijun He GRALLOC_USAGE_SW_READ_OFTEN; 562a7677722304670dc07feef242156b97e6bb51bcdZhijun He int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | 563a7677722304670dc07feef242156b97e6bb51bcdZhijun He GRALLOC_USAGE_HW_RENDER; 564a7677722304670dc07feef242156b97e6bb51bcdZhijun He boolean previewConsumer = ((usageFlags & disallowedFlags) == 0 && 565a7677722304670dc07feef242156b97e6bb51bcdZhijun He (usageFlags & allowedFlags) != 0); 566a7677722304670dc07feef242156b97e6bb51bcdZhijun He int surfaceFormat = ImageFormat.UNKNOWN; 567a7677722304670dc07feef242156b97e6bb51bcdZhijun He try { 568a7677722304670dc07feef242156b97e6bb51bcdZhijun He surfaceFormat = detectSurfaceType(output); 569a7677722304670dc07feef242156b97e6bb51bcdZhijun He } catch(BufferQueueAbandonedException e) { 570a7677722304670dc07feef242156b97e6bb51bcdZhijun He throw new IllegalArgumentException("Surface was abandoned", e); 571a7677722304670dc07feef242156b97e6bb51bcdZhijun He } 572a7677722304670dc07feef242156b97e6bb51bcdZhijun He 57347ac34997b34002a81cfaac3fdf429fdf329220cZhijun He return previewConsumer; 574a7677722304670dc07feef242156b97e6bb51bcdZhijun He } 575a7677722304670dc07feef242156b97e6bb51bcdZhijun He 576a7677722304670dc07feef242156b97e6bb51bcdZhijun He public static boolean isVideoEncoderConsumer(Surface output) { 577a7677722304670dc07feef242156b97e6bb51bcdZhijun He int usageFlags = detectSurfaceUsageFlags(output); 578a7677722304670dc07feef242156b97e6bb51bcdZhijun He int disallowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | 579a7677722304670dc07feef242156b97e6bb51bcdZhijun He GRALLOC_USAGE_RENDERSCRIPT | GRALLOC_USAGE_SW_READ_OFTEN; 580a7677722304670dc07feef242156b97e6bb51bcdZhijun He int allowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER; 581a7677722304670dc07feef242156b97e6bb51bcdZhijun He boolean videoEncoderConsumer = ((usageFlags & disallowedFlags) == 0 && 582a7677722304670dc07feef242156b97e6bb51bcdZhijun He (usageFlags & allowedFlags) != 0); 583a7677722304670dc07feef242156b97e6bb51bcdZhijun He 584a7677722304670dc07feef242156b97e6bb51bcdZhijun He int surfaceFormat = ImageFormat.UNKNOWN; 585a7677722304670dc07feef242156b97e6bb51bcdZhijun He try { 586a7677722304670dc07feef242156b97e6bb51bcdZhijun He surfaceFormat = detectSurfaceType(output); 587a7677722304670dc07feef242156b97e6bb51bcdZhijun He } catch(BufferQueueAbandonedException e) { 588a7677722304670dc07feef242156b97e6bb51bcdZhijun He throw new IllegalArgumentException("Surface was abandoned", e); 589a7677722304670dc07feef242156b97e6bb51bcdZhijun He } 590a7677722304670dc07feef242156b97e6bb51bcdZhijun He 59147ac34997b34002a81cfaac3fdf429fdf329220cZhijun He return videoEncoderConsumer; 592a7677722304670dc07feef242156b97e6bb51bcdZhijun He } 593a7677722304670dc07feef242156b97e6bb51bcdZhijun He 594fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala /** 595fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * Query the surface for its currently configured usage flags 596fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala */ 597f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk static int detectSurfaceUsageFlags(Surface surface) { 598f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk checkNotNull(surface); 599f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return nativeDetectSurfaceUsageFlags(surface); 600f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 601f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 602fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala /** 603fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala * Query the surface for its currently configured format 604fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala */ 605fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186Eino-Ville Talvala public static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException { 606ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(surface); 607ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface)); 608ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk } 609ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 610e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala /** 611e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala * Query the surface for its currently configured dataspace 612e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala */ 613e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala public static int detectSurfaceDataspace(Surface surface) throws BufferQueueAbandonedException { 614e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala checkNotNull(surface); 615e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface)); 616e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala } 617e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala 61829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen static void connectSurface(Surface surface) throws BufferQueueAbandonedException { 619ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(surface); 620ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 62129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen LegacyExceptionUtils.throwOnError(nativeConnectSurface(surface)); 62229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen } 62329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 62429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen static void disconnectSurface(Surface surface) throws BufferQueueAbandonedException { 62529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if (surface == null) return; 62629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 62729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen LegacyExceptionUtils.throwOnError(nativeDisconnectSurface(surface)); 628ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk } 629ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 630ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk static void produceFrame(Surface surface, byte[] pixelBuffer, int width, 631ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk int height, int pixelFormat) 632ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk throws BufferQueueAbandonedException { 633ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(surface); 634ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(pixelBuffer); 635ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkArgumentPositive(width, "width must be positive."); 636ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkArgumentPositive(height, "height must be positive."); 637ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 638ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk LegacyExceptionUtils.throwOnError(nativeProduceFrame(surface, pixelBuffer, width, height, 639ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk pixelFormat)); 640ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk } 641ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 642ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk static void setSurfaceFormat(Surface surface, int pixelFormat) 643ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk throws BufferQueueAbandonedException { 644ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(surface); 645ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 646ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk LegacyExceptionUtils.throwOnError(nativeSetSurfaceFormat(surface, pixelFormat)); 647ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk } 648ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 649ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk static void setSurfaceDimens(Surface surface, int width, int height) 650ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk throws BufferQueueAbandonedException { 651ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkNotNull(surface); 652ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkArgumentPositive(width, "width must be positive."); 653ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk checkArgumentPositive(height, "height must be positive."); 654ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 655ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height)); 656ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk } 657ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk 6583c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk static long getSurfaceId(Surface surface) { 6593c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk checkNotNull(surface); 6603c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return nativeGetSurfaceId(surface); 6613c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6623c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 6633c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk static List<Long> getSurfaceIds(Collection<Surface> surfaces) { 6643c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (surfaces == null) { 6653c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk throw new NullPointerException("Null argument surfaces"); 6663c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6673c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk List<Long> surfaceIds = new ArrayList<>(); 6683c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk for (Surface s : surfaces) { 6693c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk long id = getSurfaceId(s); 6703c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (id == 0) { 6713c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk throw new IllegalStateException( 6723c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "Configured surface had null native GraphicBufferProducer pointer!"); 6733c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6743c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk surfaceIds.add(id); 6753c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6763c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return surfaceIds; 6773c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 6790fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk static boolean containsSurfaceId(Surface s, Collection<Long> ids) { 6803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk long id = getSurfaceId(s); 6813c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return ids.contains(id); 6823c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 68428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk static void setSurfaceOrientation(Surface surface, int facing, int sensorOrientation) 68528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk throws BufferQueueAbandonedException { 68628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk checkNotNull(surface); 68728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk LegacyExceptionUtils.throwOnError(nativeSetSurfaceOrientation(surface, facing, 68828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sensorOrientation)); 68928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 69028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 69128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk static Size getTextureSize(SurfaceTexture surfaceTexture) 69228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk throws BufferQueueAbandonedException { 69328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk checkNotNull(surfaceTexture); 69428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 69528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int[] dimens = new int[2]; 69628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk LegacyExceptionUtils.throwOnError(nativeDetectTextureDimens(surfaceTexture, 69728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk /*out*/dimens)); 69828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 69928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return new Size(dimens[0], dimens[1]); 70028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 70128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 70291838ded36131525312739c0929913b215519c2aRuben Brunk static void setNextTimestamp(Surface surface, long timestamp) 70391838ded36131525312739c0929913b215519c2aRuben Brunk throws BufferQueueAbandonedException { 70491838ded36131525312739c0929913b215519c2aRuben Brunk checkNotNull(surface); 70591838ded36131525312739c0929913b215519c2aRuben Brunk LegacyExceptionUtils.throwOnError(nativeSetNextTimestamp(surface, timestamp)); 70691838ded36131525312739c0929913b215519c2aRuben Brunk } 70791838ded36131525312739c0929913b215519c2aRuben Brunk 708a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk static void setScalingMode(Surface surface, int mode) 709a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk throws BufferQueueAbandonedException { 710a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk checkNotNull(surface); 711a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk LegacyExceptionUtils.throwOnError(nativeSetScalingMode(surface, mode)); 712a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk } 713a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 714a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 715ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk private static native int nativeDetectSurfaceType(Surface surface); 716feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 717e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala private static native int nativeDetectSurfaceDataspace(Surface surface); 718e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala 719ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk private static native int nativeDetectSurfaceDimens(Surface surface, 720a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /*out*/int[/*2*/] dimens); 721feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 72229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen private static native int nativeConnectSurface(Surface surface); 723feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 724ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, 725feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int height, int pixelFormat); 726feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 727ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk private static native int nativeSetSurfaceFormat(Surface surface, int pixelFormat); 728feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 729ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk private static native int nativeSetSurfaceDimens(Surface surface, int width, int height); 730feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 7313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk private static native long nativeGetSurfaceId(Surface surface); 73228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 73328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk private static native int nativeSetSurfaceOrientation(Surface surface, int facing, 73428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int sensorOrientation); 73528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 73628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk private static native int nativeDetectTextureDimens(SurfaceTexture surfaceTexture, 73728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk /*out*/int[/*2*/] dimens); 73828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 73991838ded36131525312739c0929913b215519c2aRuben Brunk private static native int nativeSetNextTimestamp(Surface surface, long timestamp); 7401dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 741f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk private static native int nativeDetectSurfaceUsageFlags(Surface surface); 742f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 743a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk private static native int nativeSetScalingMode(Surface surface, int scalingMode); 744a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 74529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen private static native int nativeDisconnectSurface(Surface surface); 74629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 7471dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk static native int nativeGetJpegFooterSize(); 748feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 749