我正在尝试将相同的相机输入输出到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"/>
答案 0 :(得分:0)
你的表面是什么样的?如果您共享相关的xml文件,我可以使用棒棒糖在我的nexus 5上重现它,看看发生了什么。 (我本来会把它写成评论,但我还没有这个名声。)