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

Commit 895eb28f authored by Jason Sams's avatar Jason Sams Committed by Android (Google) Code Review
Browse files

Merge "Rename ioReceive and ioSend"

parents 646a404d c5f519c5
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ public class Allocation extends BaseObj {
     * @hide
     *
     */
    public void ioSendOutput() {
    public void ioSend() {
        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
            throw new RSIllegalArgumentException(
                "Can only send buffer if IO_OUTPUT usage specified.");
@@ -374,13 +374,21 @@ public class Allocation extends BaseObj {
        mRS.nAllocationIoSend(getID());
    }

    /**
     * Delete once code is updated.
     * @hide
     */
    public void ioSendOutput() {
        ioSend();
    }

    /**
     * Receive the latest input into the Allocation.
     *
     * @hide
     *
     */
    public void ioGetInput() {
    public void ioReceive() {
        if ((mUsage & USAGE_IO_INPUT) == 0) {
            throw new RSIllegalArgumentException(
                "Can only receive if IO_INPUT usage specified.");
+29 −0
Original line number Diff line number Diff line
#
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)

# TODO: build fails with this set
# LOCAL_SDK_VERSION := current

LOCAL_PACKAGE_NAME := RsSurfaceTextureOpaque

include $(BUILD_PACKAGE)
+21 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.rs.sto">
    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:label="RsSurfaceTextureOpaque"
        android:hardwareAccelerated="true"
        android:icon="@drawable/test_pattern">

        <activity android:name="SurfaceTextureOpaque">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
+307 B
Loading image diff...
+234 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.example.android.rs.sto;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.SystemClock;
import android.util.Log;

import java.io.IOException;
import java.util.List;

public class CameraCapture {

    public interface CameraFrameListener {
        public void onNewCameraFrame();
    }

    static final int FRAMES_PER_SEC = 30;

    private Camera mCamera;
    private SurfaceTexture mSurfaceTexture;

    private int mProgram;

    private int mCameraTransformHandle;
    private int mTexSamplerHandle;
    private int mTexCoordHandle;
    private int mPosCoordHandle;

    private float[] mCameraTransform = new float[16];

    private int mCameraId = 0;
    private int mWidth;
    private int mHeight;

    private long mStartCaptureTime = 0;

    private boolean mNewFrameAvailable = false;
    private boolean mIsOpen = false;

    private CameraFrameListener mListener;

    public synchronized void beginCapture(int cameraId, int width, int height,
                                          SurfaceTexture st) {
        mCameraId = cameraId;
        mSurfaceTexture = st;

        // Open the camera
        openCamera(width, height);

        // Start the camera
        mStartCaptureTime = SystemClock.elapsedRealtime();
        mCamera.startPreview();
        mIsOpen = true;
    }

    public void getCurrentFrame() {
        if (checkNewFrame()) {
            if (mStartCaptureTime > 0 && SystemClock.elapsedRealtime() - mStartCaptureTime > 2000) {
                // Lock white-balance and exposure for effects
                Log.i("CC", "Locking white-balance and exposure!");
                Camera.Parameters params = mCamera.getParameters();
                params.setAutoWhiteBalanceLock(true);
                params.setAutoExposureLock(true);
                //mCamera.setParameters(params);
                mStartCaptureTime = 0;
            }

            mSurfaceTexture.updateTexImage();
            mSurfaceTexture.getTransformMatrix(mCameraTransform);

            // display it here
        }
    }

    public synchronized boolean hasNewFrame() {
        return mNewFrameAvailable;
    }

    public synchronized void endCapture() {
        mIsOpen = false;
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
            mSurfaceTexture = null;
        }
    }

    public synchronized boolean isOpen() {
        return mIsOpen;
    }

    public int getWidth() {
        return mWidth;
    }

    public int getHeight() {
        return mHeight;
    }

    public void setCameraFrameListener(CameraFrameListener listener) {
        mListener = listener;
    }

    private void openCamera(int width, int height) {
        // Setup camera
        mCamera = Camera.open(mCameraId);
        mCamera.setParameters(calcCameraParameters(width, height));

        // Create camera surface texture
        try {
            mCamera.setPreviewTexture(mSurfaceTexture);
        } catch (IOException e) {
            throw new RuntimeException("Could not bind camera surface texture: " +
                                       e.getMessage() + "!");
        }

        // Connect SurfaceTexture to callback
        mSurfaceTexture.setOnFrameAvailableListener(onCameraFrameAvailableListener);
    }

    private Camera.Parameters calcCameraParameters(int width, int height) {
        Camera.Parameters params = mCamera.getParameters();
        params.setPreviewSize(mWidth, mHeight);

        // Find closest size
        int closestSize[] = findClosestSize(width, height, params);
        mWidth = closestSize[0];
        mHeight = closestSize[1];
        params.setPreviewSize(mWidth, mHeight);

        // Find closest FPS
        int closestRange[] = findClosestFpsRange(FRAMES_PER_SEC, params);

        params.setPreviewFpsRange(closestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
                                  closestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);

        return params;
    }

    private int[] findClosestSize(int width, int height, Camera.Parameters parameters) {
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        int closestWidth = -1;
        int closestHeight = -1;
        int smallestWidth = previewSizes.get(0).width;
        int smallestHeight =  previewSizes.get(0).height;
        for (Camera.Size size : previewSizes) {
            // Best match defined as not being larger in either dimension than
            // the requested size, but as close as possible. The below isn't a
            // stable selection (reording the size list can give different
            // results), but since this is a fallback nicety, that's acceptable.
            if ( size.width <= width &&
                 size.height <= height &&
                 size.width >= closestWidth &&
                 size.height >= closestHeight) {
                closestWidth = size.width;
                closestHeight = size.height;
            }
            if ( size.width < smallestWidth &&
                 size.height < smallestHeight) {
                smallestWidth = size.width;
                smallestHeight = size.height;
            }
        }
        if (closestWidth == -1) {
            // Requested size is smaller than any listed size; match with smallest possible
            closestWidth = smallestWidth;
            closestHeight = smallestHeight;
        }
        int[] closestSize = {closestWidth, closestHeight};
        return closestSize;
    }

    private int[] findClosestFpsRange(int fps, Camera.Parameters params) {
        List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange();
        int[] closestRange = supportedFpsRanges.get(0);
        int fpsk = fps * 1000;
        int minDiff = 1000000;
        for (int[] range : supportedFpsRanges) {
            int low = range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
            int high = range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
            if (low <= fpsk && high >= fpsk) {
                int diff = (fpsk - low) + (high - fpsk);
                if (diff < minDiff) {
                    closestRange = range;
                    minDiff = diff;
                }
            }
        }
        Log.i("CC", "Found closest range: "
            + closestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] + " - "
            + closestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
        return closestRange;
    }

    private synchronized void signalNewFrame() {
        mNewFrameAvailable = true;
        if (mListener != null) {
            mListener.onNewCameraFrame();
        }
    }

    private synchronized boolean checkNewFrame() {
        if (mNewFrameAvailable) {
            mNewFrameAvailable = false;
            return true;
        }
        return false;
    }

    private SurfaceTexture.OnFrameAvailableListener onCameraFrameAvailableListener =
            new SurfaceTexture.OnFrameAvailableListener() {
        @Override
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            signalNewFrame();
        }
    };
}
Loading