Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69421363 authored by Chien-Yu Chen's avatar Chien-Yu Chen Committed by Android (Google) Code Review
Browse files

Merge "ImageWriter: Exception when Surface is abandoned" into mnc-dev

parents 7a64e976 e0ee6304
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -497,8 +497,9 @@ public abstract class CameraCaptureSession implements AutoCloseable {
     *
     * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess
     * capture requests get the input images from, rather than the camera device. The application
     * can create a {@link android.media.ImageWriter} with this input {@link Surface} and use it to
     * provide input images for reprocess capture requests.</p>
     * can create a {@link android.media.ImageWriter ImageWriter} with this input {@link Surface}
     * and use it to provide input images for reprocess capture requests. When the reprocessable
     * capture session is closed, the input {@link Surface} is abandoned and becomes invalid.</p>
     *
     * @return The {@link Surface} where reprocessing capture requests get the input images from. If
     *         this is not a reprocess capture session, {@code null} will be returned.
+19 −5
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ import java.util.List;
 * Several Android API classes can provide input {@link android.view.Surface
 * Surface} objects for ImageWriter to produce data into, including
 * {@link MediaCodec MediaCodec} (encoder),
 * {@link android.hardware.camera2.CameraDevice CameraDevice} (reprocessing
 * input), {@link ImageReader}, etc.
 * {@link android.hardware.camera2.CameraCaptureSession CameraCaptureSession}
 * (reprocessing input), {@link ImageReader}, etc.
 * </p>
 * <p>
 * The input Image data is encapsulated in {@link Image} objects. To produce
@@ -64,7 +64,14 @@ import java.util.List;
 * {@link android.hardware.camera2.CameraDevice}) to consume the Images. If the
 * downstream components cannot consume the Images at least as fast as the
 * ImageWriter production rate, the {@link #dequeueInputImage} call will
 * eventually block and the application will have to drop input frames. </p>
 * eventually block and the application will have to drop input frames.
 * </p>
 * <p>
 * If the consumer component that provided the input {@link android.view.Surface Surface}
 * abandons the {@link android.view.Surface Surface}, {@link #queueInputImage queueing}
 * or {@link #dequeueInputImage dequeueing} an {@link Image} will throw an
 * {@link IllegalStateException}.
 * </p>
 */
public class ImageWriter implements AutoCloseable {
    private final Object mListenerLock = new Object();
@@ -188,7 +195,9 @@ public class ImageWriter implements AutoCloseable {
     * @return The next available input Image from this ImageWriter.
     * @throws IllegalStateException if {@code maxImages} Images are currently
     *             dequeued, or the ImageWriter format is
     *             {@link ImageFormat#PRIVATE PRIVATE}.
     *             {@link ImageFormat#PRIVATE PRIVATE}, or the input
     *             {@link android.view.Surface Surface} has been abandoned by the
     *             consumer component that provided the {@link android.view.Surface Surface}.
     * @see #queueInputImage
     * @see Image#close
     */
@@ -254,6 +263,11 @@ public class ImageWriter implements AutoCloseable {
     *
     * @param image The Image to be queued back to ImageWriter for future
     *            consumption.
     * @throws IllegalStateException if the image was already queued previously,
     *            or the image was aborted previously, or the input
     *            {@link android.view.Surface Surface} has been abandoned by the
     *            consumer component that provided the
     *            {@link android.view.Surface Surface}.
     * @see #dequeueInputImage()
     */
    public void queueInputImage(Image image) {
@@ -699,7 +713,7 @@ public class ImageWriter implements AutoCloseable {
        }

        private void clearSurfacePlanes() {
            if (mIsImageValid) {
            if (mIsImageValid && mPlanes != null) {
                for (int i = 0; i < mPlanes.length; i++) {
                    if (mPlanes[i] != null) {
                        mPlanes[i].clearBuffer();
+38 −6
Original line number Diff line number Diff line
@@ -338,9 +338,16 @@ static void ImageWriter_dequeueImage(JNIEnv* env, jobject thiz, jlong nativeCtx,
    int fenceFd = -1;
    status_t res = anw->dequeueBuffer(anw.get(), &anb, &fenceFd);
    if (res != OK) {
        // TODO: handle different error cases here.
        ALOGE("%s: Dequeue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
        switch (res) {
            case NO_INIT:
                jniThrowException(env, "java/lang/IllegalStateException",
                    "Surface has been abandoned");
                break;
            default:
                // TODO: handle other error cases here.
                jniThrowRuntimeException(env, "dequeue buffer failed");
        }
        return;
    }
    // New GraphicBuffer object doesn't own the handle, thus the native buffer
@@ -468,7 +475,16 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j
    // Finally, queue input buffer
    res = anw->queueBuffer(anw.get(), buffer, fenceFd);
    if (res != OK) {
        ALOGE("%s: Queue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
        switch (res) {
            case NO_INIT:
                jniThrowException(env, "java/lang/IllegalStateException",
                    "Surface has been abandoned");
                break;
            default:
                // TODO: handle other error cases here.
                jniThrowRuntimeException(env, "Queue input buffer failed");
        }
        return;
    }

@@ -514,9 +530,16 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
    // Step 1. Attach Image
    res = surface->attachBuffer(opaqueBuffer->mGraphicBuffer.get());
    if (res != OK) {
        // TODO: handle different error case separately.
        ALOGE("Attach image failed: %s (%d)", strerror(-res), res);
        switch (res) {
            case NO_INIT:
                jniThrowException(env, "java/lang/IllegalStateException",
                    "Surface has been abandoned");
                break;
            default:
                // TODO: handle other error cases here.
                jniThrowRuntimeException(env, "nativeAttachImage failed!!!");
        }
        return res;
    }
    sp < ANativeWindow > anw = surface;
@@ -545,7 +568,16 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
    res = anw->queueBuffer(anw.get(), opaqueBuffer->mGraphicBuffer.get(), /*fenceFd*/
            -1);
    if (res != OK) {
        ALOGE("%s: Queue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
        switch (res) {
            case NO_INIT:
                jniThrowException(env, "java/lang/IllegalStateException",
                    "Surface has been abandoned");
                break;
            default:
                // TODO: handle other error cases here.
                jniThrowRuntimeException(env, "Queue input buffer failed");
        }
        return res;
    }