|
|
@ -6,7 +6,6 @@ import android.location.Location; |
|
|
|
|
|
|
|
|
|
|
|
import android.media.CamcorderProfile; |
|
|
|
import android.media.CamcorderProfile; |
|
|
|
import android.media.MediaRecorder; |
|
|
|
import android.media.MediaRecorder; |
|
|
|
import android.os.Build; |
|
|
|
|
|
|
|
import android.os.Handler; |
|
|
|
import android.os.Handler; |
|
|
|
import android.os.Looper; |
|
|
|
import android.os.Looper; |
|
|
|
import android.support.annotation.NonNull; |
|
|
|
import android.support.annotation.NonNull; |
|
|
@ -15,6 +14,7 @@ import android.support.annotation.WorkerThread; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import java.util.Collection; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
|
|
|
|
abstract class CameraController implements |
|
|
|
abstract class CameraController implements |
|
|
@ -56,11 +56,12 @@ abstract class CameraController implements |
|
|
|
protected Mapper mMapper; |
|
|
|
protected Mapper mMapper; |
|
|
|
protected FrameManager mFrameManager; |
|
|
|
protected FrameManager mFrameManager; |
|
|
|
protected SizeSelector mPictureSizeSelector; |
|
|
|
protected SizeSelector mPictureSizeSelector; |
|
|
|
|
|
|
|
protected SizeSelector mVideoSizeSelector; |
|
|
|
protected MediaRecorder mMediaRecorder; |
|
|
|
protected MediaRecorder mMediaRecorder; |
|
|
|
protected VideoResult mVideoResult; |
|
|
|
protected VideoResult mVideoResult; |
|
|
|
protected long mVideoMaxSize; |
|
|
|
protected long mVideoMaxSize; |
|
|
|
protected int mVideoMaxDuration; |
|
|
|
protected int mVideoMaxDuration; |
|
|
|
protected Size mPictureSize; |
|
|
|
protected Size mCaptureSize; |
|
|
|
protected Size mPreviewSize; |
|
|
|
protected Size mPreviewSize; |
|
|
|
protected int mPreviewFormat; |
|
|
|
protected int mPreviewFormat; |
|
|
|
|
|
|
|
|
|
|
@ -280,6 +281,10 @@ abstract class CameraController implements |
|
|
|
mPictureSizeSelector = selector; |
|
|
|
mPictureSizeSelector = selector; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final void setVideoSizeSelector(SizeSelector selector) { |
|
|
|
|
|
|
|
mVideoSizeSelector = selector; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final void setVideoMaxSize(long videoMaxSizeBytes) { |
|
|
|
final void setVideoMaxSize(long videoMaxSizeBytes) { |
|
|
|
mVideoMaxSize = videoMaxSizeBytes; |
|
|
|
mVideoMaxSize = videoMaxSizeBytes; |
|
|
|
} |
|
|
|
} |
|
|
@ -385,10 +390,14 @@ abstract class CameraController implements |
|
|
|
return mAudio; |
|
|
|
return mAudio; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final SizeSelector getPictureSizeSelector() { |
|
|
|
/* for tests */ final SizeSelector getPictureSizeSelector() { |
|
|
|
return mPictureSizeSelector; |
|
|
|
return mPictureSizeSelector; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* for tests */ final SizeSelector getVideoSizeSelector() { |
|
|
|
|
|
|
|
return mVideoSizeSelector; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final float getZoomValue() { |
|
|
|
final float getZoomValue() { |
|
|
|
return mZoomValue; |
|
|
|
return mZoomValue; |
|
|
|
} |
|
|
|
} |
|
|
@ -444,8 +453,13 @@ abstract class CameraController implements |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final Size getPictureSize(int reference) { |
|
|
|
final Size getPictureSize(int reference) { |
|
|
|
if (mPictureSize == null) return null; |
|
|
|
if (mCaptureSize == null || mMode == Mode.VIDEO) return null; |
|
|
|
return flip(REF_SENSOR, reference) ? mPictureSize.flip() : mPictureSize; |
|
|
|
return flip(REF_SENSOR, reference) ? mCaptureSize.flip() : mCaptureSize; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final Size getVideoSize(int reference) { |
|
|
|
|
|
|
|
if (mCaptureSize == null || mMode == Mode.PICTURE) return null; |
|
|
|
|
|
|
|
return flip(REF_SENSOR, reference) ? mCaptureSize.flip() : mCaptureSize; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final Size getPreviewSize(int reference) { |
|
|
|
final Size getPreviewSize(int reference) { |
|
|
@ -465,43 +479,33 @@ abstract class CameraController implements |
|
|
|
* But when it does, the {@link CameraPreview.SurfaceCallback} should be called, |
|
|
|
* But when it does, the {@link CameraPreview.SurfaceCallback} should be called, |
|
|
|
* and this should be refreshed. |
|
|
|
* and this should be refreshed. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected final Size computePictureSize() { |
|
|
|
protected final Size computeCaptureSize() { |
|
|
|
// The external selector is expecting stuff in the view world, not in the sensor world.
|
|
|
|
// We want to pass stuff into the REF_VIEW reference, not the sensor one.
|
|
|
|
// Use the list in the camera options, then flip the result if needed.
|
|
|
|
// This is already managed by CameraOptions, so we just flip again at the end.
|
|
|
|
boolean flip = flip(REF_SENSOR, REF_VIEW); |
|
|
|
boolean flip = flip(REF_SENSOR, REF_VIEW); |
|
|
|
SizeSelector selector; |
|
|
|
SizeSelector selector; |
|
|
|
|
|
|
|
Collection<Size> sizes; |
|
|
|
if (mMode == Mode.PICTURE) { |
|
|
|
if (mMode == Mode.PICTURE) { |
|
|
|
selector = SizeSelectors.or(mPictureSizeSelector, SizeSelectors.biggest()); |
|
|
|
selector = mPictureSizeSelector; |
|
|
|
|
|
|
|
sizes = mCameraOptions.getSupportedPictureSizes(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// The Camcorder internally checks for cameraParameters.getSupportedVideoSizes() etc.
|
|
|
|
selector = mVideoSizeSelector; |
|
|
|
// And we want the picture size to be the biggest picture consistent with the video aspect ratio.
|
|
|
|
sizes = mCameraOptions.getSupportedVideoSizes(); |
|
|
|
// -> Use the external picture selector, but enforce the ratio constraint.
|
|
|
|
|
|
|
|
CamcorderProfile profile = getCamcorderProfile(); |
|
|
|
|
|
|
|
AspectRatio targetRatio = AspectRatio.of(profile.videoFrameWidth, profile.videoFrameHeight); |
|
|
|
|
|
|
|
if (flip) targetRatio = targetRatio.inverse(); |
|
|
|
|
|
|
|
LOG.i("size:", "computeCaptureSize:", "targetRatio:", targetRatio); |
|
|
|
|
|
|
|
SizeSelector matchRatio = SizeSelectors.aspectRatio(targetRatio, 0); |
|
|
|
|
|
|
|
selector = SizeSelectors.or( |
|
|
|
|
|
|
|
SizeSelectors.and(matchRatio, mPictureSizeSelector), |
|
|
|
|
|
|
|
SizeSelectors.and(matchRatio), |
|
|
|
|
|
|
|
mPictureSizeSelector |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
selector = SizeSelectors.or(selector, SizeSelectors.biggest()); |
|
|
|
List<Size> list = new ArrayList<>(mCameraOptions.getSupportedPictureSizes()); |
|
|
|
List<Size> list = new ArrayList<>(sizes); |
|
|
|
Size result = selector.select(list).get(0); |
|
|
|
Size result = selector.select(list).get(0); |
|
|
|
LOG.i("computePictureSize:", "result:", result, "flip:", flip); |
|
|
|
LOG.i("computeCaptureSize:", "result:", result, "flip:", flip); |
|
|
|
if (flip) result = result.flip(); |
|
|
|
if (flip) result = result.flip(); // Go back to REF_SENSOR
|
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected final Size computePreviewSize(List<Size> previewSizes) { |
|
|
|
protected final Size computePreviewSize(List<Size> previewSizes) { |
|
|
|
// instead of flipping everything to the view world, we can just flip the
|
|
|
|
// instead of flipping everything to REF_VIEW, we can just flip the
|
|
|
|
// surface size to the sensor world
|
|
|
|
// surface size from REF_VIEW to REF_SENSOR, and reflip at the end.
|
|
|
|
AspectRatio targetRatio = AspectRatio.of(mPictureSize.getWidth(), mPictureSize.getHeight()); |
|
|
|
AspectRatio targetRatio = AspectRatio.of(mCaptureSize.getWidth(), mCaptureSize.getHeight()); |
|
|
|
Size targetMinSize = mPreview.getSurfaceSize(); |
|
|
|
Size targetMinSize = mPreview.getSurfaceSize(); |
|
|
|
boolean flip = flip(REF_SENSOR, REF_VIEW); |
|
|
|
boolean flip = flip(REF_VIEW, REF_SENSOR); |
|
|
|
if (flip) targetMinSize = targetMinSize.flip(); |
|
|
|
if (flip) targetMinSize = targetMinSize.flip(); |
|
|
|
LOG.i("size:", "computePreviewSize:", "targetRatio:", targetRatio, "targetMinSize:", targetMinSize); |
|
|
|
LOG.i("size:", "computePreviewSize:", "targetRatio:", targetRatio, "targetMinSize:", targetMinSize); |
|
|
|
SizeSelector matchRatio = SizeSelectors.and( // Match this aspect ratio and sort by biggest
|
|
|
|
SizeSelector matchRatio = SizeSelectors.and( // Match this aspect ratio and sort by biggest
|
|
|
@ -522,10 +526,5 @@ abstract class CameraController implements |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@NonNull |
|
|
|
|
|
|
|
protected final CamcorderProfile getCamcorderProfile() { |
|
|
|
|
|
|
|
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//endregion
|
|
|
|
//endregion
|
|
|
|
} |
|
|
|
} |
|
|
|