Android相机捕获请求和多个目标曲面的问题

时间:2015-03-24 02:37:13

标签: java android android-camera android-5.0-lollipop

我正在尝试将相同的相机输入输出到2个surfaceTextures。如果我只针对其中一个曲面,应用程序运行正常(当然只有一个显示摄像头输入)。如果我同时瞄准它们,它会在相机进纸冻结之前工作很短的时间。当它冻结时,会调用onCaptureFailed方法(包含在CameraCaptureSession.CaptureCallback中)。 我正在使用运行Android 5.1的Nexus 5。 这是我的代码:

package com.jackdelano.capstone2;

import android.app.Activity;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.Range;
import android.util.Size;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.hardware.camera2.CameraDevice;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;


public class CameraActivity extends Activity {


    HandlerThread myHandlerThread;
    Handler myHandler;
    CameraManager myCameraManager;
    String myCameraId; //either 0 or 1 I think
    CameraDevice myCameraDevice;
    TextureView myTextureView1;
    TextureView myTextureView2;
    List<Surface> mySurfaceList;
    CameraCharacteristics myCameraCharacteristics;
    CaptureRequest.Builder myBuilder;
    Surface mySurface1;
    Surface mySurface2;
    boolean surfaceTexture1Available;
    boolean surfaceTexture2Available;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);

        myCameraId = "0";

        surfaceTexture1Available = false;
        surfaceTexture2Available = false;

        myTextureView1 = (TextureView) findViewById(R.id.myTextureView1);
        myTextureView2 = (TextureView) findViewById(R.id.myTextureView2);

        myTextureView1.setSurfaceTextureListener(mySurfaceTexture1Listener);
        myTextureView2.setSurfaceTextureListener(mySurfaceTexture2Listener);


        myHandlerThread = new HandlerThread("Camera");
        myHandlerThread.start();
        myHandler = new Handler(myHandlerThread.getLooper());

        myCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);


    }

    void startPreview()
    {
        SurfaceTexture mySurfaceTexture1 = myTextureView1.getSurfaceTexture();
        SurfaceTexture mySurfaceTexture2 = myTextureView2.getSurfaceTexture();

        try {
            myCameraCharacteristics = myCameraManager.getCameraCharacteristics(myCameraId);
        }catch(CameraAccessException e) {
            e.printStackTrace();
        }

        StreamConfigurationMap configs = myCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

        Size dimensions1 = configs.getOutputSizes(mySurfaceTexture1.getClass())[0];
        mySurfaceTexture1.setDefaultBufferSize(dimensions1.getWidth(), dimensions1.getHeight());
        Size dimensions2 = configs.getOutputSizes(mySurfaceTexture2.getClass())[0];
        mySurfaceTexture2.setDefaultBufferSize(dimensions2.getWidth(), dimensions2.getHeight());


        mySurface1 = new Surface(mySurfaceTexture1);
        mySurface2 = new Surface(mySurfaceTexture2);

        mySurfaceList = new ArrayList<Surface>();
        mySurfaceList.add(mySurface1);
        mySurfaceList.add(mySurface2);

        try {
            myCameraDevice.createCaptureSession(mySurfaceList, myCameraCaptureSessionStateCallback, myHandler);
        }catch(CameraAccessException e){
            e.printStackTrace();
        }

    }

TextureView.SurfaceTextureListener mySurfaceTexture1Listener = new TextureView.SurfaceTextureListener(){
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture _surfaceTexture, int width, int height) {

        surfaceTexture1Available = true;
        if(surfaceTexture2Available) {
            try {
                myCameraManager.openCamera(myCameraId, myCameraDeviceStateCallback, myHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture _surfaceTexture) {

        return true;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture _surfaceTexture, int width, int height) {

    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture _surfaceTexture) {

    }
};

    TextureView.SurfaceTextureListener mySurfaceTexture2Listener = new TextureView.SurfaceTextureListener(){
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture _surfaceTexture, int width, int height) {

            surfaceTexture2Available = true;
            if(surfaceTexture1Available) {
                try {
                    myCameraManager.openCamera(myCameraId, myCameraDeviceStateCallback, myHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture _surfaceTexture) {

            return true;
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture _surfaceTexture, int width, int height) {

        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture _surfaceTexture) {

        }
    };

    private CameraDevice.StateCallback myCameraDeviceStateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(CameraDevice _cameraDevice) {
            myCameraDevice = _cameraDevice;
            startPreview();
        }

        @Override
        public void onDisconnected(CameraDevice _cameradevice) {

        }

        @Override
        public void onError(CameraDevice _cameradevice, int i) {
            Log.d("JUMBO", "Camera Device Error");
        }
    };

    private CameraCaptureSession.StateCallback myCameraCaptureSessionStateCallback = new CameraCaptureSession.StateCallback() {

        @Override
        public void onConfigureFailed(CameraCaptureSession _cameraCaptureSession) {
        }

        public void onConfigured(CameraCaptureSession myCameraCaptureSession) {
            try {
                myBuilder = myCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }

//THIS IS WHERE I TARGET THE SURFACES. IF ONE OF THESE LINES IS OMITTED, BEHAVIOR IS AS EXPECTED.
            myBuilder.addTarget(mySurface1);
            myBuilder.addTarget(mySurface2);

            CaptureRequest myCaptureRequest = myBuilder.build();

            try {
                myCameraCaptureSession.setRepeatingRequest(myCaptureRequest, myCameraCaptureSessionCaptureCallback, myHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }

        }
    };

private CameraCaptureSession.CaptureCallback myCameraCaptureSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {

    @Override
    public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
        Log.d("JUMBO", "capture failed" + Integer.toString(failure.getReason()));

    }
};


    void toast(String string) {
        Toast.makeText(this, string, Toast.LENGTH_LONG).show();
    }



}

XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jackdelano.capstone2.CameraActivity">

<TextureView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/myTextureView1"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp" />

<TextureView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/myTextureView2"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp"/>

1 个答案:

答案 0 :(得分:0)

你的表面是什么样的?如果您共享相关的xml文件,我可以使用棒棒糖在我的nexus 5上重现它,看看发生了什么。 (我本来会把它写成评论,但我还没有这个名声。)