I am not able to get a constant framerate with the camera2 API using MediaRecorder on the Galaxy S9 front camera.
Essentially I am using the example Project from https://github.com/googlesamples/android-Camera2Video but stripped it down to find the error. I removed the mTextureView and use only the mediaRecorder surface.
Here are the relevant code snippets:
#Override
protected void setUpMediaRecorder() throws IOException {
final Activity activity = getActivity();
if (null == activity) {
return;
}
// Camcorder Profile QUALITY_HIGH doenst work
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncodingBitRate(30000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(2560, 1440);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.prepare();
}
#Override
protected void setUpCaptureRequestBuilder(CaptureRequest.Builder builder) {
Range<Integer> range = getRange();
builder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, range);
}
// get highest range
private Range<Integer> getRange() {
CameraManager mCameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics chars = null;
try {
chars = mCameraManager.getCameraCharacteristics(mCameraManager.getCameraIdList()[1]);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Range<Integer>[] ranges = chars.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
Range<Integer> result = null;
for (Range<Integer> range : ranges) {
if (result == null) {
result = range;
} else {
int upper = range.getUpper();
int lower = range.getLower();
if (upper >= result.getUpper() && lower >= result.getLower()) {
result = range;
}
}
}
return result;
}
protected void startRecordingVideo() {
if (null == mCameraDevice) {
return;
}
try {
closeCaptureSession();
setUpMediaRecorder();
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
List<Surface> surfaces = new ArrayList<>();
// Set up Surface for the MediaRecorder
Surface recorderSurface = mMediaRecorder.getSurface();
surfaces.add(recorderSurface);
mPreviewBuilder.addTarget(recorderSurface);
// Start a capture session
// Once the session starts, we can update the UI and start recording
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
mCaptureSession = cameraCaptureSession;
setUpCaptureRequestBuilder(mPreviewBuilder);
if (null == mCameraDevice) {
return;
}
try {
mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// UI
mButtonVideo.setText(R.string.stop);
mIsRecordingVideo = true;
// Start recording
mMediaRecorder.start();
}
});
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Activity activity = getActivity();
if (null != activity) {
Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
}
}
}, mBackgroundHandler);
} catch (CameraAccessException | IOException e) {
e.printStackTrace();
}
}
getRange() returns a Range of [30,30]. So it should record at 30fps. If I move the camera to some darker areas the frame rate suddenly drops. If locking the AE while moving to a light area the framerate is stable, even in dark areas.
So it seems to have something to do with AE but can not figure out what. Any help?
Related
I am using Camera2 API (https://github.com/googlearchive/android-Camera2Basic) for my project.
I want to use Front and Rear both camera, It’s working properly on my device
Realme5
Android: 10
But when I am trying to use front camera on
One Plus 6, Android: 10 or Samsung Galaxy J7 Nxt, Android 7.0 Or Redmi.
Then I am going on onConfigureFailed method and it’s redirect me firstActivity
Manifest ScreenShots:enter image description here
Log ScreenShots:enter image description here
Whole code in googlearchive GitHub link is given above
Variable Initialisation
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String FRAGMENT_DIALOG = "dialog";
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
public static int mSelectedFacing = 1;
flip camera button click
if (mTextureView.isAvailable()) {
if(mSelectedFacing ==0){
mSelectedFacing = 1;
}else {
mSelectedFacing = 0;
}
closeCamera();
openCamera(mTextureView.getWidth(), mTextureView.getHeight(), mSelectedFacing);
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
Open camera
private void openCamera(int width, int height,int mSelectedFacing) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
setUpCameraOutputs(width, height,mSelectedFacing);
configureTransform(width, height);
Activity activity = getActivity();
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
try {
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
}
}
Close camera
private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
if (null != mCaptureSession) {
mCaptureSession.close();
mCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mImageReader) {
mImageReader.close();
mImageReader = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
} finally {
mCameraOpenCloseLock.release();
}
}
CameraPreviewSession
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder
= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Flash is automatically enabled when necessary.
setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(
#NonNull CameraCaptureSession cameraCaptureSession) {
showToast("Failed");
}
}, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Please help me …
Thanks in advance
I have do like it will capture image in background without any preview screen using Camera2 API in background service.
Visit https://codepalyers.blogspot.com/2020/12/capture-image-in-background-without.html
If you wish to use rear camera use
private final String frontCamera = "1";
private final String backCamera = "0";
as already define in code.
I want to create a custom camera app in android. I have one activity that uses two fragments. One fragment is for camera and another is for show picture or video that was taken. When activity starts, It loads camera fragment. In preview of camera there is a button that uses for record video. In long press on button recording starts and after end of long press video recording stops and file is send to the fragment that show the video. In other word, at the end of long press on button I replace the camera fragment with a new fragment that show the result. In onPause of camera fragment I stopped the cameradevice but after some back and forth between fragments I can't use the camera at all. After some back and forth no camera application doesn't work in my phone and I have to restart my phone.
these are some codes of my camera fragment
#OnLongClick(R.id.capture)
public boolean captureLongPressed() {
startRecord();
mMediaRecorder.start();
return true;
}
#OnTouch(R.id.capture)
public boolean captureOnTouch(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isRecordButtonLongPressed) {
mIsRecording = false;
try {
mMediaRecorder.stop();
mMediaRecorder.reset();
} catch (RuntimeException ex) {
}
if (listener != null)
listener.onVideoRecorded(mVideoFileName);
return true;
}
}
return false;
}
private void startRecord() {
try {
setupMediaRecorder();
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
Surface recordSurface = mMediaRecorder.getSurface();
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mCaptureRequestBuilder.addTarget(previewSurface);
mCaptureRequestBuilder.addTarget(recordSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
try {
session.setRepeatingRequest(mCaptureRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession session) {
}
}, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setupMediaRecorder() throws IOException {
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mVideoFileName);
mMediaRecorder.setVideoEncodingBitRate(1000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setOrientationHint(mTotalRotation);
mMediaRecorder.prepare();
}
#Override
public void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
private void closeCamera() {
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
I was trying to use the Camera2 API of Android. The front camera is working fine, but when it comes to using the back/rear camera, this error occurs:
LegacyCameraDevice_nativeGetSurfaceId: Could not retrieve native Surface from surface.
This problem occurs after I click the button to take a picture. The capture callback is successful, but I get no image in onImageAvailable().
I followed the tutorial of https://web.archive.org/web/20161011160303/https://inducesmile.com/android/android-camera2-api-example-tutorial/ . I do not have any idea on how to proceed with the error that I am facing right now.
Here is the code used in capturing the image:
private void takePicture() {
if (mCameraDevice == null) {
return;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
CameraManager mManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics mCharacteristics = mManager.getCameraCharacteristics(mCameraDevice.getId());
Size[] jpegSizes = null;
if (mCharacteristics != null) {
jpegSizes = mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
}
int width = 640;
int height = 480;
for(int x = 0; x < jpegSizes.length; x++) {
Log.wtf("jpegSizes", String.valueOf(jpegSizes[x]));
}
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[4].getWidth();
height = jpegSizes[4].getHeight();
}
final ImageReader mReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> mOutputSurface = new ArrayList<>(2);
mOutputSurface.add(mReader.getSurface());
mOutputSurface.add(new Surface(mTextureView.getSurfaceTexture()));
final CaptureRequest.Builder mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
mCaptureBuilder.addTarget(mReader.getSurface());
mCaptureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
int mRotation = getWindowManager().getDefaultDisplay().getRotation();
int jpegOrientation = (ORIENTATIONS.get(mRotation) + mSensorOrientation + 270) % 360;
if(cameraId.equals("0")) {
mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(mRotation));
} else {
if(extras.getString("orient").equals("landscape")) {
mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(mRotation));
} else {
mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, jpegOrientation);
}
}
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
if(mImage == null) {
Toast.makeText(StartCameraActivity.this, "Capturing Image Failed, Please Try Again", Toast.LENGTH_SHORT).show();
Log.wtf("onCaptureComplete", "Image not Available");
} else {
Log.wtf("onCaptureComplete", "Image Available");
}
//createCameraPreview();
}
#Override
public void onCaptureFailed(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
Log.wtf("FAILED", failure.toString());
}
};
mCameraDevice.createCaptureSession(mOutputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
Log.wtf("onConfigured", "succes");
try {
session.capture(mCaptureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession session) {
Log.wtf("onConfigureFailed", "failed");
}
}, mBackgroundHandler);
mReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(final ImageReader reader) {
mImage = reader.acquireLatestImage();
Log.wtf("imageAvail", "OnImageAvailable");
StartCameraActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mImage == null) {
return;
}
final Image.Plane[] planes = mImage.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mTextureView.setVisibility(View.INVISIBLE);
if(cameraId.equals("0")) {
screenshotHolder.setImageBitmap(bitmap);
} else {
screenshotHolder.setImageBitmap(flip(bitmap, mImage.getWidth(), mImage.getHeight()));
}
new RenderPicture(StartCameraActivity.this).execute();
if (mImage != null) {
mImage.close();
}
if(mReader != null) {
mReader.close();
}
}
});
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
Your ImageReader is a local variable in takePicture, and doesn't look like it's stored anywhere in the parent class. It's likely being garbage collected immediately or soon after takePicture exits, so when the camera tries to set itself up, the Surface reports as being abandoned.
A Surface is like a weak reference and won't keep the ImageReader alive by itself. Store it in the parent class like you do with the camera device.
I am new to camera2 api. I want to build an image processing framework on my Android phone.
Step1: use the Camera2 API to open a camera preview stream
Step2: feed the preview frame data to OpenCV for processing
Step3: display the processed result live on the screen
Currently, I have finished Step1 using ImageReader and C++ OpenCV code. However, I don't know how to do step3.
How do I display the processed image on the screen? (I want to display the normal image, and overlay an icon if I detect predefined object)
Here are some key codes:
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
// Surface surface = new Surface(texture);
Surface mImageSurface = mImageReader.getSurface();
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// captureRequestBuilder.addTarget(surface);
captureRequestBuilder.addTarget(mImageSurface);
cameraDevice.createCaptureSession(Arrays.asList(mImageSurface), new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview() {
if(null == cameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Log.e(TAG, "onImageAvailable: " + count++);
Image img = null;
img = reader.acquireNextImage();
try {
if (img == null) throw new NullPointerException("cannot be null");
ByteBuffer buffer = img.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
int width = img.getWidth();
int height = img.getHeight();
// ****try to get captured img for display here (synchronized)
// ****try to process image for detecting the object here (asynchronized)
} catch (NullPointerException ex) {
ex.printStackTrace();
}finally {
Log.e(TAG, "in the finally! ------------");
if (img != null)
img.close();
}
}
};
guys who can give me an example how to use camera2 characteristics in android?
F.e. how to use CONTROL_EFFECT_MODE_SEPIA effect ?
Have tried to use characteristics.get(CameraCharacteristics.CONTROL_EFFECT_MODE_SEPIA), but it gave me an The method get(CameraCharacteristics.Key<T>) in the type CameraCharacteristics is not applicable for the arguments (int).
Thanks.
Neither first one nor second one didn't work for me. I am sure i am doing something wrong, so i want to show my code, and hope you can help me to find a solution.
#Override
public void openCamera() {
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "openCamera E");
try {
String cameraId = manager.getCameraIdList()[0];
characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
Log.e(TAG, "Preview size is: " + mPreviewSize.toString());
manager.openCamera(cameraId, mStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
public void updatePreview() {
if(null == mCameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_OFF);
HandlerThread thread = new HandlerThread("CameraPreview");
thread.start();
backgroundHandler = new Handler(thread.getLooper());
try {
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void startPreview() {
if(null == mCameraDevice || !myTexture.isAvailable() || null == mPreviewSize) {
Log.e(TAG, "startPreview fail, return");
}
SurfaceTexture texture = myTexture.getSurfaceTexture();
if(null == texture) {
Log.e(TAG,"texture is null, return");
return;
}
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
try {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
try {
mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
mPreviewSession = session;
updatePreview();
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
Log.e(TAG,"onConfiguration failed.");
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
Log.e(TAG, "onOpened");
mCameraDevice = camera;
startPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
Log.e(TAG, "onDisconnected");
}
#Override
public void onError(CameraDevice camera, int error) {
Log.e(TAG, "onError");
}
};
You need to set the effect mode in your CaptureRequest; CameraCharacteristics will tell you what effect modes are supported.
Roughly, use:
int[] supportedEffects = characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS);
int selectedEffect = supportedEffects[0]; // select effect you want here
requestBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, selectedEffect);
captureSession.setRepeatingRequest(requestBuilder.build());
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
mPreviewBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_NEGATIVE);
mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), mPreviewSessionCallback, mHandler);
exaple:https://github.com/pinguo-yuyidong/Camera2/blob/master/app/src/main/java/us/yydcdut/androidltest/listener/EffectItemClickListener.java