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

Commit fd6f39e1 authored by Jamie Gennis's avatar Jamie Gennis
Browse files

Enable camera preview to a SurfaceTexture.

This change adds a public Java API to use a SurfaceTexture as the
destination of camera preview frames.

Change-Id: If537fed2df12c5c181e2af5f817985c1bda853fb
parent b5e18555
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -90535,6 +90535,19 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
<method name="setPreviewTexture"
 return="void"
 abstract="false"
 native="true"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="surfaceTexture" type="android.graphics.SurfaceTexture">
</parameter>
</method>
<method name="setZoomChangeListener"
 return="void"
 abstract="false"
+28 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -324,8 +325,10 @@ public class Camera {

    /**
     * Sets the {@link Surface} to be used for live preview.
     * A surface is necessary for preview, and preview is necessary to take
     * pictures.  The same surface can be re-set without harm.
     * Either a surface or surface texture is necessary for preview, and
     * preview is necessary to take pictures.  The same surface can be re-set
     * without harm.  Setting a preview surface will un-set any preview surface
     * texture that was set via {@link #setPreviewTexture}.
     *
     * <p>The {@link SurfaceHolder} must already contain a surface when this
     * method is called.  If you are using {@link android.view.SurfaceView},
@@ -356,6 +359,29 @@ public class Camera {

    private native final void setPreviewDisplay(Surface surface);

    /**
     * Sets the {@link SurfaceTexture} to be used for live preview.
     * Either a surface or surface texture is necessary for preview, and
     * preview is necessary to take pictures.  The same surface texture can be
     * re-set without harm.  Setting a preview surface texture will un-set any
     * preview surface that was set via {@link #setPreviewDisplay}.
     *
     * <p>This method must be called before {@link #startPreview()}.  The
     * one exception is that if the preview surface texture is not set (or set
     * to null) before startPreview() is called, then this method may be called
     * once with a non-null parameter to set the preview surface.  (This allows
     * camera setup and surface creation to happen in parallel, saving time.)
     * The preview surface texture may not otherwise change while preview is
     * running.
     *
     * @param surfaceTexture the {@link SurfaceTexture} to which the preview
     *     images are to be sent or null to remove the current preview surface
     *     texture
     * @throws IOException if the method fails (for example, if the surface
     *     texture is unavailable or unsuitable).
     */
    public native final void setPreviewTexture(SurfaceTexture surfaceTexture);

    /**
     * Callback interface used to deliver copies of preview frames as
     * they are displayed.
+25 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <utils/Vector.h>

#include <gui/SurfaceTexture.h>
#include <surfaceflinger/Surface.h>
#include <camera/Camera.h>
#include <binder/IMemory.h>
@@ -34,6 +35,7 @@ using namespace android;
struct fields_t {
    jfieldID    context;
    jfieldID    surface;
    jfieldID    surfaceTexture;
    jfieldID    facing;
    jfieldID    orientation;
    jmethodID   post_event;
@@ -393,6 +395,24 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz,
    }
}

static void android_hardware_Camera_setPreviewTexture(JNIEnv *env,
        jobject thiz, jobject jSurfaceTexture)
{
    LOGV("setPreviewTexture");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    sp<SurfaceTexture> surfaceTexture = NULL;
    if (jSurfaceTexture != NULL) {
        surfaceTexture = reinterpret_cast<SurfaceTexture*>(env->GetIntField(
                jSurfaceTexture, fields.surfaceTexture));
    }
    if (camera->setPreviewTexture(surfaceTexture) != NO_ERROR) {
        jniThrowException(env, "java/io/IOException",
                "setPreviewTexture failed");
    }
}

static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
    LOGV("startPreview");
@@ -603,6 +623,9 @@ static JNINativeMethod camMethods[] = {
  { "setPreviewDisplay",
    "(Landroid/view/Surface;)V",
    (void *)android_hardware_Camera_setPreviewDisplay },
  { "setPreviewTexture",
    "(Landroid/graphics/SurfaceTexture;)V",
    (void *)android_hardware_Camera_setPreviewTexture },
  { "startPreview",
    "()V",
    (void *)android_hardware_Camera_startPreview },
@@ -688,6 +711,8 @@ int register_android_hardware_Camera(JNIEnv *env)
    field fields_to_find[] = {
        { "android/hardware/Camera", "mNativeContext",   "I", &fields.context },
        { "android/view/Surface",    ANDROID_VIEW_SURFACE_JNI_ID, "I", &fields.surface },
        { "android/graphics/SurfaceTexture",
          ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I", &fields.surfaceTexture },
        { "android/hardware/Camera$CameraInfo", "facing",   "I", &fields.facing },
        { "android/hardware/Camera$CameraInfo", "orientation",   "I", &fields.orientation },
    };
@@ -708,4 +733,3 @@ int register_android_hardware_Camera(JNIEnv *env)
    return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",
                                              camMethods, NELEM(camMethods));
}