Removed VideoQuality.

pull/360/head
Mattia Iavarone 7 years ago
parent a37caf0760
commit acf1b4cdde
  1. 3
      MIGRATION.md
  2. 22
      README.md
  3. 4
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraOptions1Test.java
  4. 9
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  5. 50
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java
  6. 5
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  7. 33
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  8. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java
  9. 51
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  10. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java
  11. 43
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  12. 73
      cameraview/src/main/options/com/otaliastudios/cameraview/VideoQuality.java
  13. 1
      cameraview/src/main/utils/com/otaliastudios/cameraview/CropHelper.java
  14. 5
      demo/src/main/java/com/otaliastudios/cameraview/demo/Control.java

@ -21,4 +21,5 @@
setMode() and cameraMode.
- CameraOptions.isVideoSnapshotSupported(): removed, this would be ambiguous now. While in video
mode, you can only use takePictureSnapshot(), not takePicture().
- takePicture(): will now throw an exception if called when Mode == Mode.VIDEO. You can only take snapshots.
- takePicture(): will now throw an exception if called when Mode == Mode.VIDEO. You can only take snapshots.
- VideoQuality: this has been removed.

@ -135,6 +135,7 @@ To capture an image just call `CameraView.takePicture()`. Make sure you setup a
to handle the image callback.
```java
camera.setMode(Mode.PICTURE);
camera.addCameraListener(new CameraListener() {
@Override
public void onPictureTaken(PictureResult result) {
@ -160,6 +161,7 @@ To capture video just call `CameraView.takeVideo(file)` to start, and
the video callback.
```java
camera.setMode(Mode.VIDEO);
camera.addCameraListener(new CameraListener() {
@Override
public void onVideoTaken(VideoResult result) {
@ -427,7 +429,6 @@ Most camera parameters can be controlled through XML attributes or linked method
|[`cameraFacing`](#camerafacing)|`setFacing()`|`back` `front`|`back`|
|[`cameraFlash`](#cameraflash)|`setFlash()`|`off` `on` `auto` `torch`|`off`|
|[`cameraGrid`](#cameragrid)|`setGrid()`|`off` `draw3x3` `draw4x4` `drawPhi`|`off`|
|[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`lowest` `highest` `maxQvga` `max480p` `max720p` `max1080p` `max2160p`|`max480p`|
|[`cameraVideoCodec`](#cameravideocodec)|`setVideoCodec()`|`deviceDefault` `h263` `h264`|`deviceDefault`|
|[`cameraWhiteBalance`](#camerawhitebalance)|`setWhiteBalance()`|`auto` `incandescent` `fluorescent` `daylight` `cloudy`|`auto`|
|[`cameraHdr`](#camerahdr)|`setHdr()`|`off` `on`|`off`|
@ -440,9 +441,8 @@ Most camera parameters can be controlled through XML attributes or linked method
What to capture - either picture or video. This has a couple of consequences:
- Sizing: picture and preview size are chosen among the available picture or video sizes,
depending on the flag. The picture size is chosen according to the given [size selector](#picture-size).
When `video`, in addition, we try to match the `videoQuality` aspect ratio.
- Sizing: the capture size is chosen among the available picture or video sizes,
depending on the flag. The picture size is chosen according to the given [picture size selector](#picture-size).
- Capturing: while in picture mode, `takeVideo` will throw an exception.
- Capturing: while in video mode, `takePicture` will throw an exception, but picture snapshots are supported.
- Permission behavior: when requesting a `video` session, the record audio permission will be requested.
@ -485,20 +485,6 @@ cameraView.setGrid(Grid.DRAW_4X4);
cameraView.setGrid(Grid.DRAW_PHI);
```
#### cameraVideoQuality
Sets the desired video quality.
```java
cameraView.setVideoQuality(VideoQuality.LOWEST);
cameraView.setVideoQuality(VideoQuality.HIGHEST);
cameraView.setVideoQuality(VideoQuality.MAX_QVGA);
cameraView.setVideoQuality(VideoQuality.MAX_480P);
cameraView.setVideoQuality(VideoQuality.MAX_720P);
cameraView.setVideoQuality(VideoQuality.MAX_1080P);
cameraView.setVideoQuality(VideoQuality.MAX_2160P);
```
#### cameraVideoCodec
Sets the encoder for video recordings.

@ -133,11 +133,11 @@ public class CameraOptions1Test extends BaseTest {
CameraOptions o = new CameraOptions(params, false);
Collection<Grid> grids = o.getSupportedControls(Grid.class);
Collection<VideoQuality> video = o.getSupportedControls(VideoQuality.class);
Collection<VideoCodec> video = o.getSupportedControls(VideoCodec.class);
Collection<Mode> sessions = o.getSupportedControls(Mode.class);
Collection<Audio> audio = o.getSupportedControls(Audio.class);
assertEquals(grids.size(), Grid.values().length);
assertEquals(video.size(), VideoQuality.values().length);
assertEquals(video.size(), VideoCodec.values().length);
assertEquals(sessions.size(), Mode.values().length);
assertEquals(audio.size(), Audio.values().length);
}

@ -88,7 +88,6 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getMode(), Mode.DEFAULT);
assertEquals(cameraView.getHdr(), Hdr.DEFAULT);
assertEquals(cameraView.getAudio(), Audio.DEFAULT);
assertEquals(cameraView.getVideoQuality(), VideoQuality.DEFAULT);
assertEquals(cameraView.getVideoCodec(), VideoCodec.DEFAULT);
assertEquals(cameraView.getLocation(), null);
assertEquals(cameraView.getExposureCorrection(), 0f, 0f);
@ -526,14 +525,6 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getAudio(), Audio.OFF);
}
@Test
public void testVideoQuality() {
cameraView.set(VideoQuality.MAX_1080P);
assertEquals(cameraView.getVideoQuality(), VideoQuality.MAX_1080P);
cameraView.set(VideoQuality.LOWEST);
assertEquals(cameraView.getVideoQuality(), VideoQuality.LOWEST);
}
@Test
public void testVideoCodec() {
cameraView.set(VideoCodec.H_263);

@ -152,12 +152,6 @@ public class IntegrationTest extends BaseTest {
controller.mStartVideoTask.await(400);
}
private void waitForVideoQuality(VideoQuality quality) {
controller.mVideoQualityTask.listen();
camera.setVideoQuality(quality);
controller.mVideoQualityTask.await(400);
}
//region test open/close
@Test
@ -384,50 +378,6 @@ public class IntegrationTest extends BaseTest {
//endregion
//region testSetVideoQuality
// This can be tricky because can trigger layout changes.
@Test(expected = RuntimeException.class)
public void testSetVideoQuality_whileRecording() throws Throwable {
// Can't run on Travis, MediaRecorder not supported.
// Error while starting MediaRecorder. java.lang.RuntimeException: start failed.
camera.setMode(Mode.VIDEO);
waitForVideoQuality(VideoQuality.HIGHEST);
waitForOpen(true);
waitForVideoStart();
waitForVideoQuality(VideoQuality.LOWEST);
waitForUiException();
}
@Test
public void testSetVideoQuality_whileInPictureMode() {
camera.setMode(Mode.PICTURE);
waitForVideoQuality(VideoQuality.HIGHEST);
waitForOpen(true);
waitForVideoQuality(VideoQuality.LOWEST);
assertEquals(camera.getVideoQuality(), VideoQuality.LOWEST);
}
@Test
public void testSetVideoQuality_whileNotStarted() {
waitForVideoQuality(VideoQuality.HIGHEST);
assertEquals(camera.getVideoQuality(), VideoQuality.HIGHEST);
waitForVideoQuality(VideoQuality.LOWEST);
assertEquals(camera.getVideoQuality(), VideoQuality.LOWEST);
}
@Test
public void testSetVideoQuality_shouldRecompute() {
// TODO:
// If video quality changes bring to a new capture size,
// this might bring to a new aspect ratio,
// which might bring to a new preview size. No idea how to test.
assertTrue(true);
}
//endregion
//region test takeVideo
@Test(expected = RuntimeException.class)

@ -66,11 +66,6 @@ public class MockCameraController extends CameraController {
mWhiteBalance = whiteBalance;
}
@Override
void setVideoQuality(VideoQuality videoQuality) {
mVideoQuality = videoQuality;
}
@Override
void setMode(Mode mode) {
mMode = mode;

@ -464,39 +464,6 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setVideoQuality(VideoQuality videoQuality) {
final VideoQuality old = mVideoQuality;
mVideoQuality = videoQuality;
schedule(mVideoQualityTask, true, new Runnable() {
@Override
public void run() {
if (mIsTakingVideo) {
// TODO: actually any call to getParameters() could fail while recording a video.
// See. https://stackoverflow.com/questions/14941625/
mVideoQuality = old;
throw new IllegalStateException("Can't change video quality while recording a video.");
}
if (mMode == Mode.VIDEO) {
// Change capture size to a size that fits the video aspect ratio.
Size oldSize = mPictureSize;
mPictureSize = computePictureSize();
if (!mPictureSize.equals(oldSize)) {
// New video quality triggers a new aspect ratio.
// Go on and see if preview size should change also.
Camera.Parameters params = mCamera.getParameters();
params.setPictureSize(mPictureSize.getWidth(), mPictureSize.getHeight());
mCamera.setParameters(params);
onSurfaceChanged();
}
LOG.i("setVideoQuality:", "captureSize:", mPictureSize);
LOG.i("setVideoQuality:", "previewSize:", mPreviewSize);
}
}
});
}
@Override
void takePicture() {
LOG.v("takePicture: scheduling");

@ -80,11 +80,6 @@ class Camera2 extends CameraController {
}
@Override
void setVideoQuality(VideoQuality videoQuality) {
}
@Override
void takePicture() {

@ -42,7 +42,6 @@ abstract class CameraController implements
protected Facing mFacing;
protected Flash mFlash;
protected WhiteBalance mWhiteBalance;
protected VideoQuality mVideoQuality;
protected VideoCodec mVideoCodec;
protected Mode mMode;
protected Hdr mHdr;
@ -325,9 +324,6 @@ abstract class CameraController implements
// Just set.
abstract void setAudio(Audio audio);
// Throw if capturing. If in video session, recompute capture size, and, if needed, preview size.
abstract void setVideoQuality(VideoQuality videoQuality);
abstract void takePicture();
abstract void takePictureSnapshot(AspectRatio viewAspectRatio);
@ -361,10 +357,6 @@ abstract class CameraController implements
return mWhiteBalance;
}
final VideoQuality getVideoQuality() {
return mVideoQuality;
}
final VideoCodec getVideoCodec() {
return mVideoCodec;
}
@ -488,7 +480,7 @@ abstract class CameraController implements
CamcorderProfile profile = getCamcorderProfile();
AspectRatio targetRatio = AspectRatio.of(profile.videoFrameWidth, profile.videoFrameHeight);
if (flip) targetRatio = targetRatio.inverse();
LOG.i("size:", "computeCaptureSize:", "videoQuality:", mVideoQuality, "targetRatio:", targetRatio);
LOG.i("size:", "computeCaptureSize:", "targetRatio:", targetRatio);
SizeSelector matchRatio = SizeSelectors.aspectRatio(targetRatio, 0);
selector = SizeSelectors.or(
SizeSelectors.and(matchRatio, mPictureSizeSelector),
@ -532,46 +524,7 @@ abstract class CameraController implements
@NonNull
protected final CamcorderProfile getCamcorderProfile() {
switch (mVideoQuality) {
case HIGHEST:
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH);
case MAX_2160P:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_2160P);
}
// Don't break.
case MAX_1080P:
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_1080P)) {
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_1080P);
}
// Don't break.
case MAX_720P:
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_720P)) {
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_720P);
}
// Don't break.
case MAX_480P:
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_480P)) {
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_480P);
}
// Don't break.
case MAX_QVGA:
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_QVGA)) {
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_QVGA);
}
// Don't break.
case LOWEST:
default:
// Fallback to lowest.
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_LOW);
}
return CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH);
}
//endregion

@ -150,8 +150,8 @@ public class CameraOptions {
return (Collection<T>) getSupportedHdr();
} else if (controlClass.equals(Mode.class)) {
return (Collection<T>) Arrays.asList(Mode.values());
} else if (controlClass.equals(VideoQuality.class)) {
return (Collection<T>) Arrays.asList(VideoQuality.values());
} else if (controlClass.equals(VideoCodec.class)) {
return (Collection<T>) Arrays.asList(VideoCodec.values());
} else if (controlClass.equals(WhiteBalance.class)) {
return (Collection<T>) getSupportedWhiteBalance();
}

@ -100,7 +100,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
Flash flash = Flash.fromValue(a.getInteger(R.styleable.CameraView_cameraFlash, Flash.DEFAULT.value()));
Grid grid = Grid.fromValue(a.getInteger(R.styleable.CameraView_cameraGrid, Grid.DEFAULT.value()));
WhiteBalance whiteBalance = WhiteBalance.fromValue(a.getInteger(R.styleable.CameraView_cameraWhiteBalance, WhiteBalance.DEFAULT.value()));
VideoQuality videoQuality = VideoQuality.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoQuality, VideoQuality.DEFAULT.value()));
Mode mode = Mode.fromValue(a.getInteger(R.styleable.CameraView_cameraMode, Mode.DEFAULT.value()));
Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value()));
Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value()));
@ -170,7 +169,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setFacing(facing);
setFlash(flash);
setMode(mode);
setVideoQuality(videoQuality);
setWhiteBalance(whiteBalance);
setGrid(grid);
setHdr(hdr);
@ -658,8 +656,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setHdr((Hdr) control);
} else if (control instanceof Mode) {
setMode((Mode) control);
} else if (control instanceof VideoQuality) {
setVideoQuality((VideoQuality) control);
} else if (control instanceof WhiteBalance) {
setWhiteBalance((WhiteBalance) control);
} else if (control instanceof VideoCodec) {
@ -1007,8 +1003,9 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
/**
* Sets picture capture size. The {@link SizeSelector} will be invoked with the list of available
* size, and the first acceptable size will be accepted and passed to the internal engine.
* Sets picture capture size for picture mode.
* The {@link SizeSelector} will be invoked with the list of available size, and the first
* acceptable size will be accepted and passed to the internal engine.
* See the {@link SizeSelectors} class for handy utilities for creating selectors.
*
* @param selector a size selector
@ -1018,35 +1015,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
/**
* Sets video recording quality. This is not guaranteed to be supported by current device.
* If it's not, a lower quality will be chosen, until a supported one is found.
* If sessionType is video, this might trigger a camera restart and a change in preview size.
*
* @see VideoQuality#LOWEST
* @see VideoQuality#HIGHEST
* @see VideoQuality#MAX_QVGA
* @see VideoQuality#MAX_480P
* @see VideoQuality#MAX_720P
* @see VideoQuality#MAX_1080P
* @see VideoQuality#MAX_2160P
*
* @param videoQuality requested video quality
*/
public void setVideoQuality(VideoQuality videoQuality) {
mCameraController.setVideoQuality(videoQuality);
}
/**
* Gets the current video quality.
* @return the current video quality
*/
public VideoQuality getVideoQuality() {
return mCameraController.getVideoQuality();
}
/**
* Adds a {@link CameraListener} instance to be notified of all
* interesting events that happen during the camera lifecycle.
@ -1235,8 +1203,9 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
/**
* Returns the size used for the capture, or null if it hasn't been computed
* (for example if the surface is not ready). The size is rotated to match the output orientation.
* Returns the size used for pictures taken with {@link #takePicture()},
* or null if it hasn't been computed (for example if the surface is not ready).
* The size is rotated to match the output orientation.
*
* @return the size of pictures
*/

@ -1,73 +0,0 @@
package com.otaliastudios.cameraview;
/**
* Constants for selecting the quality of video recordings.
*
* @see CameraView#setVideoQuality(VideoQuality)
*/
public enum VideoQuality implements Control {
/**
* Quality level corresponding to the lowest available resolution.
*/
LOWEST(0),
/**
* Quality level corresponding to the highest available resolution.
*/
HIGHEST(1),
/**
* Quality level corresponding to the QVGA (320x240) resolution.
*/
MAX_QVGA(2),
/**
* Quality level corresponding to the 480p (720 x 480) resolution.
* Note that the horizontal resolution for 480p can also be other
* values, such as 640 or 704, instead of 720.
*/
MAX_480P(3),
/**
* Quality level corresponding to the 720p (1280 x 720) resolution.
*/
MAX_720P(4),
/**
* Quality level corresponding to the 1080p (1920 x 1080) resolution.
* Note that the vertical resolution for 1080p can also be 1088,
* instead of 1080 (used by some vendors to avoid cropping during
* video playback).
*/
MAX_1080P(5),
/**
* Quality level corresponding to the 2160p (3840x2160) resolution.
*/
MAX_2160P(6);
static final VideoQuality DEFAULT = MAX_480P;
private int value;
VideoQuality(int value) {
this.value = value;
}
int value() {
return value;
}
static VideoQuality fromValue(int value) {
VideoQuality[] list = VideoQuality.values();
for (VideoQuality action : list) {
if (action.value() == value) {
return action;
}
}
return null;
}
}

@ -4,6 +4,7 @@ import android.graphics.Rect;
class CropHelper {
// It's important that size and aspect ratio belong to the same reference.
static Rect computeCrop(Size currentSize, AspectRatio targetRatio) {
int currentWidth = currentSize.getWidth();
int currentHeight = currentSize.getHeight();

@ -12,7 +12,6 @@ import com.otaliastudios.cameraview.GestureAction;
import com.otaliastudios.cameraview.Grid;
import com.otaliastudios.cameraview.Hdr;
import com.otaliastudios.cameraview.Mode;
import com.otaliastudios.cameraview.VideoQuality;
import com.otaliastudios.cameraview.WhiteBalance;
import java.util.ArrayList;
@ -30,7 +29,6 @@ public enum Control {
FLASH("Flash", false),
WHITE_BALANCE("White balance", false),
GRID("Grid", true),
VIDEO_QUALITY("Video quality", false),
HDR("Hdr", false),
AUDIO("Audio", true),
PINCH("Pinch gesture", false),
@ -76,7 +74,6 @@ public enum Control {
case WHITE_BALANCE: return options.getSupportedControls(WhiteBalance.class);
case HDR: return options.getSupportedControls(Hdr.class);
case GRID: return options.getSupportedControls(Grid.class);
case VIDEO_QUALITY: return options.getSupportedControls(VideoQuality.class);
case AUDIO: return options.getSupportedControls(Audio.class);
case PINCH:
case HSCROLL:
@ -111,7 +108,6 @@ public enum Control {
case FLASH: return view.getFlash();
case WHITE_BALANCE: return view.getWhiteBalance();
case GRID: return view.getGrid();
case VIDEO_QUALITY: return view.getVideoQuality();
case AUDIO: return view.getAudio();
case HDR: return view.getHdr();
case PINCH: return view.getGestureAction(Gesture.PINCH);
@ -137,7 +133,6 @@ public enum Control {
case FLASH:
case WHITE_BALANCE:
case GRID:
case VIDEO_QUALITY:
case AUDIO:
case HDR:
camera.set((com.otaliastudios.cameraview.Control) value);

Loading…
Cancel
Save