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

Commit c5f519c5 authored by Jason Sams's avatar Jason Sams
Browse files

Rename ioReceive and ioSend

First checkin of Allocation IO test

Change-Id: I26379e442796caab95a089dbb42b02192f4cc563
parent 75ec6784
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