Compare commits

...

2 Commits

Author SHA1 Message Date
dionysis 01ae02d1de Enable frame processor in v2 + logs 2018-07-19 23:38:38 +02:00
dionysis de85bb4999 Revert "Disabled preview callbacks in Camera2 to increase the frame rate of the preview."
This reverts commit 2b355554d1.
2018-07-19 22:54:57 +02:00
8 changed files with 246 additions and 204 deletions
+1
View File
@@ -3,6 +3,7 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath "com.android.tools.build:gradle:${project.androidBuildToolsVersion}"
@@ -78,12 +78,14 @@ public class V2Provider implements CameraProvider {
CaptureRequestFactory captureRequestFactory = new CaptureRequestFactory(
cameraConnection,
stillSurfaceReader,
continuousSurfaceReader,
textureManager,
parametersProvider
);
SessionProvider sessionProvider = new SessionProvider(
stillSurfaceReader,
continuousSurfaceReader,
cameraConnection,
captureRequestFactory,
textureManager,
@@ -8,6 +8,7 @@ import android.support.annotation.RequiresApi;
import android.view.Surface;
import io.fotoapparat.hardware.v2.connection.CameraConnection;
import io.fotoapparat.hardware.v2.readers.ContinuousSurfaceReader;
import io.fotoapparat.hardware.v2.readers.StillSurfaceReader;
import io.fotoapparat.hardware.v2.surface.TextureManager;
import io.fotoapparat.parameter.Flash;
@@ -21,16 +22,19 @@ import io.fotoapparat.parameter.range.Range;
public class CaptureRequestFactory {
private final StillSurfaceReader surfaceReader;
private final ContinuousSurfaceReader continuousSurfaceReader;
private final TextureManager textureManager;
private final ParametersProvider parametersProvider;
private final CameraConnection cameraConnection;
public CaptureRequestFactory(CameraConnection cameraConnection,
StillSurfaceReader surfaceReader,
ContinuousSurfaceReader continuousSurfaceReader,
TextureManager textureManager,
ParametersProvider parametersProvider) {
this.cameraConnection = cameraConnection;
this.surfaceReader = surfaceReader;
this.continuousSurfaceReader = continuousSurfaceReader;
this.textureManager = textureManager;
this.parametersProvider = parametersProvider;
}
@@ -45,6 +49,7 @@ public class CaptureRequestFactory {
CameraDevice camera = cameraConnection.getCamera();
Surface viewSurface = textureManager.getSurface();
Surface frameSurface = continuousSurfaceReader.getSurface();
Flash flash = parametersProvider.getFlash();
Range<Integer> previewFpsRange = parametersProvider.getPreviewFpsRange();
Integer sensorSensitivity = parametersProvider.getSensorSensitivity();
@@ -52,7 +57,7 @@ public class CaptureRequestFactory {
return CaptureRequestBuilder
.create(camera, CameraDevice.TEMPLATE_PREVIEW)
.into(viewSurface)
.into(viewSurface, frameSurface)
.flash(flash)
.previewFpsRange(previewFpsRange)
.sensorSensitivity(sensorSensitivity)
@@ -12,6 +12,7 @@ import io.fotoapparat.hardware.CameraException;
import io.fotoapparat.hardware.v2.CameraThread;
import io.fotoapparat.hardware.v2.connection.CameraConnection;
import io.fotoapparat.hardware.v2.parameters.CaptureRequestFactory;
import io.fotoapparat.hardware.v2.readers.ContinuousSurfaceReader;
import io.fotoapparat.hardware.v2.readers.StillSurfaceReader;
import io.fotoapparat.hardware.v2.surface.TextureManager;
@@ -23,15 +24,18 @@ public class SessionProvider implements TextureManager.Listener {
private PreviewSession previewSession;
private StillSurfaceReader surfaceReader;
private ContinuousSurfaceReader continuousSurfaceReader;
private CameraConnection connection;
private CaptureRequestFactory captureRequestFactory;
private CameraThread cameraThread;
public SessionProvider(StillSurfaceReader surfaceReader,
ContinuousSurfaceReader continuousSurfaceReader,
CameraConnection connection,
CaptureRequestFactory captureRequestFactory,
TextureManager textureManager, CameraThread cameraThread) {
this.surfaceReader = surfaceReader;
this.continuousSurfaceReader = continuousSurfaceReader;
this.connection = connection;
this.captureRequestFactory = captureRequestFactory;
this.cameraThread = cameraThread;
@@ -43,7 +47,8 @@ public class SessionProvider implements TextureManager.Listener {
CameraDevice camera = connection.getCamera();
Surface captureSurface = surfaceReader.getSurface();
List<Surface> surfaces = Arrays.asList(surface, captureSurface);
Surface frameSurface = continuousSurfaceReader.getSurface();
List<Surface> surfaces = Arrays.asList(surface, captureSurface, frameSurface);
try {
CaptureRequest previewRequest = captureRequestFactory.createPreviewRequest();
+5 -9
View File
@@ -1,9 +1,9 @@
#Configuration
androidBuildToolsVersion=2.3.2
buildToolsVersion=25.0.2
compileSdkVersion=25
androidBuildToolsVersion=3.1.0
buildToolsVersion=27.0.3
compileSdkVersion=27
minSdkVersion=14
targetSdkVersion=25
targetSdkVersion=27
#Dependencies
@@ -17,8 +17,4 @@ mockitoVersion=2.2.28
#Gradle Properties
gradleVersion=4.0
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx1536m
org.gradle.configureondemand=true
gradleVersion=4.8
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
+1
View File
@@ -24,4 +24,5 @@ dependencies {
compile project(':fotoapparat')
compile "com.android.support:appcompat-v7:${project.appCompatVersion}"
compile "io.reactivex.rxjava2:rxjava:${project.rxjava2Version}"
}
@@ -4,13 +4,18 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;
import org.reactivestreams.Subscription;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.fotoapparat.Fotoapparat;
import io.fotoapparat.FotoapparatSwitcher;
@@ -26,6 +31,13 @@ import io.fotoapparat.preview.FrameProcessor;
import io.fotoapparat.result.PendingResult;
import io.fotoapparat.result.PhotoResult;
import io.fotoapparat.view.CameraView;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
import static io.fotoapparat.log.Loggers.fileLogger;
import static io.fotoapparat.log.Loggers.logcat;
@@ -47,228 +59,248 @@ import static io.fotoapparat.result.transformer.SizeTransformers.scaled;
public class MainActivity extends AppCompatActivity {
private final PermissionsDelegate permissionsDelegate = new PermissionsDelegate(this);
private boolean hasCameraPermission;
private CameraView cameraView;
private final PermissionsDelegate permissionsDelegate = new PermissionsDelegate(this);
private boolean hasCameraPermission;
private CameraView cameraView;
private FotoapparatSwitcher fotoapparatSwitcher;
private Fotoapparat frontFotoapparat;
private Fotoapparat backFotoapparat;
private FotoapparatSwitcher fotoapparatSwitcher;
private Fotoapparat frontFotoapparat;
private Fotoapparat backFotoapparat;
private Disposable rate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraView = (CameraView) findViewById(R.id.camera_view);
hasCameraPermission = permissionsDelegate.hasCameraPermission();
cameraView = (CameraView) findViewById(R.id.camera_view);
hasCameraPermission = permissionsDelegate.hasCameraPermission();
if (hasCameraPermission) {
cameraView.setVisibility(View.VISIBLE);
} else {
permissionsDelegate.requestCameraPermission();
}
if (hasCameraPermission) {
cameraView.setVisibility(View.VISIBLE);
} else {
permissionsDelegate.requestCameraPermission();
}
setupFotoapparat();
setupFotoapparat();
takePictureOnClick();
focusOnLongClick();
switchCameraOnClick();
toggleTorchOnSwitch();
zoomSeekBar();
}
takePictureOnClick();
focusOnLongClick();
switchCameraOnClick();
toggleTorchOnSwitch();
zoomSeekBar();
}
private void setupFotoapparat() {
frontFotoapparat = createFotoapparat(LensPosition.FRONT);
backFotoapparat = createFotoapparat(LensPosition.BACK);
fotoapparatSwitcher = FotoapparatSwitcher.withDefault(backFotoapparat);
}
private void setupFotoapparat() {
frontFotoapparat = createFotoapparat(LensPosition.FRONT);
backFotoapparat = createFotoapparat(LensPosition.BACK);
fotoapparatSwitcher = FotoapparatSwitcher.withDefault(backFotoapparat);
}
private void zoomSeekBar() {
SeekBar seekBar = (SeekBar) findViewById(R.id.zoomSeekBar);
private void zoomSeekBar() {
SeekBar seekBar = (SeekBar) findViewById(R.id.zoomSeekBar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
fotoapparatSwitcher
.getCurrentFotoapparat()
.setZoom(progress / (float) seekBar.getMax());
}
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
fotoapparatSwitcher
.getCurrentFotoapparat()
.setZoom(progress / (float) seekBar.getMax());
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing
}
});
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing
}
});
}
private void toggleTorchOnSwitch() {
SwitchCompat torchSwitch = (SwitchCompat) findViewById(R.id.torchSwitch);
private void toggleTorchOnSwitch() {
SwitchCompat torchSwitch = (SwitchCompat) findViewById(R.id.torchSwitch);
torchSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
fotoapparatSwitcher
.getCurrentFotoapparat()
.updateParameters(
UpdateRequest.builder()
.flash(
isChecked
? torch()
: off()
)
.build()
);
}
});
}
torchSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
fotoapparatSwitcher
.getCurrentFotoapparat()
.updateParameters(
UpdateRequest.builder()
.flash(
isChecked
? torch()
: off()
)
.build()
);
}
});
}
private void switchCameraOnClick() {
View switchCameraButton = findViewById(R.id.switchCamera);
switchCameraButton.setVisibility(
canSwitchCameras()
? View.VISIBLE
: View.GONE
);
switchCameraOnClick(switchCameraButton);
}
private void switchCameraOnClick() {
View switchCameraButton = findViewById(R.id.switchCamera);
switchCameraButton.setVisibility(
canSwitchCameras()
? View.VISIBLE
: View.GONE
);
switchCameraOnClick(switchCameraButton);
}
private void switchCameraOnClick(View view) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchCamera();
}
});
}
private void switchCameraOnClick(View view) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchCamera();
}
});
}
private void focusOnLongClick() {
cameraView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
fotoapparatSwitcher.getCurrentFotoapparat().autoFocus();
private void focusOnLongClick() {
cameraView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
fotoapparatSwitcher.getCurrentFotoapparat().autoFocus();
return true;
}
});
}
return true;
}
});
}
private void takePictureOnClick() {
cameraView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
private void takePictureOnClick() {
cameraView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
private boolean canSwitchCameras() {
return frontFotoapparat.isAvailable() == backFotoapparat.isAvailable();
}
private boolean canSwitchCameras() {
return frontFotoapparat.isAvailable() == backFotoapparat.isAvailable();
}
private Fotoapparat createFotoapparat(LensPosition position) {
return Fotoapparat
.with(this)
.cameraProvider(CameraProviders.v1()) // change this to v2 to test Camera2 API
.into(cameraView)
.previewScaleType(ScaleType.CENTER_CROP)
.photoSize(standardRatio(biggestSize()))
.lensPosition(lensPosition(position))
.focusMode(firstAvailable(
continuousFocus(),
autoFocus(),
fixed()
))
.flash(firstAvailable(
autoRedEye(),
autoFlash(),
torch(),
off()
))
.previewFpsRange(rangeWithHighestFps())
.sensorSensitivity(highestSensorSensitivity())
.frameProcessor(new SampleFrameProcessor())
.logger(loggers(
logcat(),
fileLogger(this)
))
.cameraErrorCallback(new CameraErrorCallback() {
@Override
public void onError(CameraException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
})
.build();
}
private Fotoapparat createFotoapparat(LensPosition position) {
return Fotoapparat
.with(this)
.cameraProvider(CameraProviders.v2(this))
.into(cameraView)
.previewScaleType(ScaleType.CENTER_CROP)
.photoSize(standardRatio(biggestSize()))
.lensPosition(lensPosition(position))
.focusMode(firstAvailable(
continuousFocus(),
autoFocus(),
fixed()
))
.flash(firstAvailable(
autoRedEye(),
autoFlash(),
torch(),
off()
))
.previewFpsRange(rangeWithHighestFps())
.sensorSensitivity(highestSensorSensitivity())
.frameProcessor(new SampleFrameProcessor())
.logger(loggers(
logcat(),
fileLogger(this)
))
.cameraErrorCallback(new CameraErrorCallback() {
@Override
public void onError(CameraException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
})
.build();
}
private void takePicture() {
PhotoResult photoResult = fotoapparatSwitcher.getCurrentFotoapparat().takePicture();
private void takePicture() {
PhotoResult photoResult = fotoapparatSwitcher.getCurrentFotoapparat().takePicture();
photoResult.saveToFile(new File(
getExternalFilesDir("photos"),
"photo.jpg"
));
photoResult.saveToFile(new File(
getExternalFilesDir("photos"),
"photo.jpg"
));
photoResult
.toBitmap(scaled(0.25f))
.whenAvailable(new PendingResult.Callback<BitmapPhoto>() {
@Override
public void onResult(BitmapPhoto result) {
ImageView imageView = (ImageView) findViewById(R.id.result);
photoResult
.toBitmap(scaled(0.25f))
.whenAvailable(new PendingResult.Callback<BitmapPhoto>() {
@Override
public void onResult(BitmapPhoto result) {
ImageView imageView = (ImageView) findViewById(R.id.result);
imageView.setImageBitmap(result.bitmap);
imageView.setRotation(-result.rotationDegrees);
}
});
}
imageView.setImageBitmap(result.bitmap);
imageView.setRotation(-result.rotationDegrees);
}
});
}
private void switchCamera() {
if (fotoapparatSwitcher.getCurrentFotoapparat() == frontFotoapparat) {
fotoapparatSwitcher.switchTo(backFotoapparat);
} else {
fotoapparatSwitcher.switchTo(frontFotoapparat);
}
}
private void switchCamera() {
if (fotoapparatSwitcher.getCurrentFotoapparat() == frontFotoapparat) {
fotoapparatSwitcher.switchTo(backFotoapparat);
} else {
fotoapparatSwitcher.switchTo(frontFotoapparat);
}
}
@Override
protected void onStart() {
super.onStart();
if (hasCameraPermission) {
fotoapparatSwitcher.start();
}
}
@Override
protected void onStart() {
super.onStart();
if (hasCameraPermission) {
fotoapparatSwitcher.start();
}
@Override
protected void onStop() {
super.onStop();
if (hasCameraPermission) {
fotoapparatSwitcher.stop();
}
}
rate = rateReceiver.buffer(1, TimeUnit.SECONDS, Schedulers.computation())
.map(new Function<List<Integer>, Integer>() {
@Override
public Integer apply(List<Integer> integers) {
return integers.size();
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
Log.d("Frames", integer + "fps");
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissionsDelegate.resultGranted(requestCode, permissions, grantResults)) {
fotoapparatSwitcher.start();
cameraView.setVisibility(View.VISIBLE);
}
}
@Override
protected void onStop() {
super.onStop();
if (hasCameraPermission) {
fotoapparatSwitcher.stop();
}
rate.dispose();
}
private class SampleFrameProcessor implements FrameProcessor {
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissionsDelegate.resultGranted(requestCode, permissions, grantResults)) {
fotoapparatSwitcher.start();
cameraView.setVisibility(View.VISIBLE);
}
}
@Override
public void processFrame(Frame frame) {
// Perform frame processing, if needed
}
PublishSubject<Integer> rateReceiver = PublishSubject.create();
}
private class SampleFrameProcessor implements FrameProcessor {
@Override
public void processFrame(Frame frame) {
// Log.d("Frames", "New frame obtained");
// Perform frame processing, if needed
rateReceiver.onNext(0);
}
}
}