summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorAlok Kediya <kediya@codeaurora.org>2013-11-07 13:53:09 +0530
committerAlok Kediya <kediya@codeaurora.org>2013-11-07 13:53:09 +0530
commitf5b1181157b6d7f65376c0068768f8f3f94b5d69 (patch)
tree08cd6dba279b86f87d09445db8c79a6415ae85ed /src/com
parent60bd26f5167be74685609f50a6f1b416e53a7439 (diff)
downloadandroid_packages_apps_Snap-f5b1181157b6d7f65376c0068768f8f3f94b5d69.tar.gz
android_packages_apps_Snap-f5b1181157b6d7f65376c0068768f8f3f94b5d69.tar.bz2
android_packages_apps_Snap-f5b1181157b6d7f65376c0068768f8f3f94b5d69.zip
Camera2: Adds support for longshot/burst mode
- The longshot/burst pipeline mode uses an optimized path for triggering 'takePicture()' on each shutter callback. This should improve the shot-2-shot time. In addition to this there is also support for jpeg callbacks that only contain a jpeg file path. The callback in this case will only move the file stored by the lower layers in the correct directory. - The longshot burst pipeline can be enabled via this property: "persist.camera.longshot.enable"<-"0/1" - This change will allow longshot mode to be triggered in non-zsl mode as well. (Cherry picked from: I693366a7d06d3b386a8d96f86ee9a0574749c50b) (Cherry picked from: Id630b2033f18d1c04a636597e910e695a8692ac8) Change-Id: Idda8d58fc6d889128c1812c9c5ddadca3993c246
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/camera/AndroidCameraManagerImpl.java14
-rw-r--r--src/com/android/camera/CameraManager.java7
-rw-r--r--src/com/android/camera/FocusOverlayManager.java4
-rw-r--r--src/com/android/camera/PhotoController.java2
-rw-r--r--src/com/android/camera/PhotoModule.java147
-rw-r--r--[-rwxr-xr-x]src/com/android/camera/ShutterButton.java14
-rw-r--r--src/com/android/camera/Storage.java10
-rw-r--r--src/com/android/camera/VideoModule.java3
-rw-r--r--src/com/android/camera/WideAnglePanoramaUI.java3
9 files changed, 196 insertions, 8 deletions
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
index 84dc0a8de..b72fbd0da 100644
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ b/src/com/android/camera/AndroidCameraManagerImpl.java
@@ -88,6 +88,8 @@ class AndroidCameraManagerImpl implements CameraManager {
// Histogram
private static final int SET_HISTOGRAM_MODE = 601;
private static final int SEND_HISTOGRAM_DATA = 602;
+ //LONGSHOT
+ private static final int SET_LONGSHOT = 701;
private CameraHandler mCameraHandler;
private android.hardware.Camera mCamera;
@@ -329,6 +331,11 @@ class AndroidCameraManagerImpl implements CameraManager {
case SEND_HISTOGRAM_DATA:
mCamera.sendHistogramData();
break;
+
+ case SET_LONGSHOT:
+ mCamera.setLongshot((Boolean) msg.obj);
+ break;
+
default:
throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
}
@@ -552,6 +559,13 @@ class AndroidCameraManagerImpl implements CameraManager {
mCameraHandler.obtainMessage(
ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0).sendToTarget();
}
+
+ @Override
+ public void setLongshot(boolean enable) {
+ mCameraHandler.obtainMessage(SET_LONGSHOT,
+ new Boolean(enable)).sendToTarget();
+ }
+
@Override
public void setHistogramMode(CameraDataCallback cb) {
mCameraHandler.obtainMessage(SET_HISTOGRAM_MODE, cb).sendToTarget();
diff --git a/src/com/android/camera/CameraManager.java b/src/com/android/camera/CameraManager.java
index 4c43c27b8..8ad0d52d6 100644
--- a/src/com/android/camera/CameraManager.java
+++ b/src/com/android/camera/CameraManager.java
@@ -361,5 +361,12 @@ public interface CameraManager {
*
*/
public void sendHistogramData();
+ /**
+ * Enables/Disables longshot mode.
+ *
+ * @param enable {@code true} to enable longshot mode,
+ * {@code false} to disable it.
+ */
+ public void setLongshot(boolean enable);
}
}
diff --git a/src/com/android/camera/FocusOverlayManager.java b/src/com/android/camera/FocusOverlayManager.java
index 3176ea2b9..686122723 100644
--- a/src/com/android/camera/FocusOverlayManager.java
+++ b/src/com/android/camera/FocusOverlayManager.java
@@ -580,4 +580,8 @@ public class FocusOverlayManager {
public void setZslEnable(boolean value) {
mZslEnabled = value;
}
+
+ public boolean isZslEnabled() {
+ return mZslEnabled;
+ }
}
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
index 291b5df49..f6898a34f 100644
--- a/src/com/android/camera/PhotoController.java
+++ b/src/com/android/camera/PhotoController.java
@@ -30,6 +30,8 @@ public interface PhotoController extends OnShutterButtonListener {
public static final int SNAPSHOT_IN_PROGRESS = 3;
// Switching between cameras.
public static final int SWITCHING_CAMERA = 4;
+ // Longshot mode
+ public static final int LONGSHOT = 5;
// returns the actual set zoom value
public int onZoomChanged(int requestedZoom);
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 714d64cc3..31b9e8b26 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -178,6 +178,7 @@ public class PhotoModule
private boolean mAwbLockSupported;
private boolean mContinuousFocusSupported;
private boolean mTouchAfAecFlag;
+ private boolean mLongshotSave = false;
// The degrees of the device rotated clockwise from its natural orientation.
private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
@@ -188,6 +189,9 @@ public class PhotoModule
private ContentProviderClient mMediaProviderClient;
private boolean mFaceDetectionStarted = false;
+ private static final String PERSIST_LONG_ENABLE = "persist.camera.longshot.enable";
+ private static final String PERSIST_LONG_SAVE = "persist.camera.longshot.save";
+
private static final int MINIMUM_BRIGHTNESS = 0;
private static final int MAXIMUM_BRIGHTNESS = 6;
private int mbrightness = 3;
@@ -756,6 +760,34 @@ public class PhotoModule
}
}
+ private final class LongshotShutterCallback
+ implements CameraShutterCallback {
+
+ @Override
+ public void onShutter(CameraProxy camera) {
+ mShutterCallbackTime = System.currentTimeMillis();
+ mShutterLag = mShutterCallbackTime - mCaptureStartTime;
+ Log.e(TAG, "[KPI Perf] PROFILE_SHUTTER_LAG mShutterLag = " + mShutterLag + "ms");
+ synchronized(mCameraDevice) {
+
+ if (mCameraState != LONGSHOT) {
+ return;
+ }
+
+ if (mLongshotSave) {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new LongshotPictureCallback(null));
+ } else {
+ mCameraDevice.takePicture(mHandler,new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(null));
+ }
+ }
+ }
+ }
+
private final class ShutterCallback
implements CameraShutterCallback {
@@ -821,6 +853,64 @@ public class PhotoModule
}
}
+ private final class LongshotPictureCallback implements CameraPictureCallback {
+ Location mLocation;
+
+ public LongshotPictureCallback(Location loc) {
+ mLocation = loc;
+ }
+
+ @Override
+ public void onPictureTaken(final byte [] jpegData, CameraProxy camera) {
+ if (mPaused) {
+ return;
+ }
+
+ mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
+
+ String jpegFilePath = new String(jpegData);
+ mNamedImages.nameNewImage(mCaptureStartTime);
+ NamedEntity name = mNamedImages.getNextNameEntity();
+ String title = (name == null) ? null : name.title;
+ long date = (name == null) ? -1 : name.date;
+
+ if (title == null) {
+ Log.e(TAG, "Unbalanced name/data pair");
+ return;
+ }
+
+
+ if (date == -1 ) {
+ Log.e(TAG, "Invalid filename date");
+ return;
+ }
+
+ String dstPath = Storage.DIRECTORY;
+ File sdCard = android.os.Environment.getExternalStorageDirectory();
+ File dstFile = new File(dstPath);
+ if (dstFile == null) {
+ Log.e(TAG, "Destination file path invalid");
+ return;
+ }
+
+ File srcFile = new File(jpegFilePath);
+ if (srcFile == null) {
+ Log.e(TAG, "Source file path invalid");
+ return;
+ }
+
+ if ( srcFile.renameTo(dstFile) ) {
+ Size s = mParameters.getPictureSize();
+ String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT);
+ mActivity.getMediaSaveService().addImage(
+ null, title, date, mLocation, s.width, s.height,
+ 0, null, mOnMediaSavedListener, mContentResolver, pictureFormat);
+ } else {
+ Log.e(TAG, "Failed to move jpeg file");
+ }
+ }
+ }
+
private final class JpegPictureCallback
implements CameraPictureCallback {
Location mLocation;
@@ -872,11 +962,13 @@ public class PhotoModule
mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
boolean needRestartPreview = !mIsImageCaptureIntent
+ && (mCameraState != LONGSHOT)
&& (mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL)
&& (mReceivedSnapNum == mBurstSnapNum);
if (needRestartPreview) {
setupPreview();
- }else if (mReceivedSnapNum == mBurstSnapNum){
+ }else if ((mReceivedSnapNum == mBurstSnapNum)
+ && (mCameraState != LONGSHOT)){
mFocusManager.resetTouchFocus();
setCameraState(IDLE);
}
@@ -1086,6 +1178,7 @@ public class PhotoModule
switch (state) {
case PhotoController.PREVIEW_STOPPED:
case PhotoController.SNAPSHOT_IN_PROGRESS:
+ case PhotoController.LONGSHOT:
case PhotoController.SWITCHING_CAMERA:
mUI.enableGestures(false);
break;
@@ -1162,15 +1255,30 @@ public class PhotoModule
// We don't want user to press the button again while taking a
// multi-second HDR photo.
mUI.enableShutter(false);
- mCameraDevice.takePicture(mHandler,
- new ShutterCallback(!animateBefore),
- mRawPictureCallback, mPostViewPictureCallback,
- new JpegPictureCallback(loc));
+
+ if (mCameraState == LONGSHOT) {
+ if(mLongshotSave) {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new LongshotPictureCallback(loc));
+ } else {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(loc));
+ }
+ } else {
+ mCameraDevice.takePicture(mHandler,
+ new ShutterCallback(!animateBefore),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(loc));
+ setCameraState(SNAPSHOT_IN_PROGRESS);
+ }
mNamedImages.nameNewImage(mCaptureStartTime);
mFaceDetectionStarted = false;
- setCameraState(SNAPSHOT_IN_PROGRESS);
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_CAPTURE_DONE, "Photo");
return true;
@@ -1375,6 +1483,18 @@ public class PhotoModule
|| (mCameraState == SNAPSHOT_IN_PROGRESS)
|| (mCameraState == PREVIEW_STOPPED)) return;
+ synchronized(mCameraDevice) {
+ if (mCameraState == LONGSHOT) {
+ mCameraDevice.setLongshot(false);
+ if (!mFocusManager.isZslEnabled()) {
+ setupPreview();
+ } else {
+ setCameraState(IDLE);
+ mFocusManager.resetTouchFocus();
+ }
+ }
+ }
+
// Do not do focus if there is not enough storage.
if (pressed && !canTakePicture()) return;
@@ -1448,6 +1568,21 @@ public class PhotoModule
}
@Override
+ public void onShutterButtonLongClick() {
+ if ((null != mCameraDevice) && (mCameraState == IDLE)) {
+ boolean enable = false;
+ enable = SystemProperties.getBoolean(PERSIST_LONG_ENABLE, false);
+ if ( enable ) {
+ enable = SystemProperties.getBoolean(PERSIST_LONG_SAVE, false);
+ mLongshotSave = enable;
+ mCameraDevice.setLongshot(true);
+ setCameraState(PhotoController.LONGSHOT);
+ mFocusManager.doSnap();
+ }
+ }
+ }
+
+ @Override
public void installIntentFilter() {
// Do nothing.
}
diff --git a/src/com/android/camera/ShutterButton.java b/src/com/android/camera/ShutterButton.java
index a1bbb1a0d..f1d969f9d 100755..100644
--- a/src/com/android/camera/ShutterButton.java
+++ b/src/com/android/camera/ShutterButton.java
@@ -29,7 +29,18 @@ import android.widget.ImageView;
*/
public class ShutterButton extends ImageView {
+ private class LongClickListener implements View.OnLongClickListener {
+ public boolean onLongClick(View v) {
+ if ( null != mListener ) {
+ mListener.onShutterButtonLongClick();
+ return true;
+ }
+ return false;
+ }
+ }
+
private boolean mTouchEnabled = true;
+ private LongClickListener mLongClick = new LongClickListener();
/**
* A callback to be invoked when a ShutterButton's pressed state changes.
@@ -42,6 +53,7 @@ public class ShutterButton extends ImageView {
*/
void onShutterButtonFocus(boolean pressed);
void onShutterButtonClick();
+ void onShutterButtonLongClick();
}
private OnShutterButtonListener mListener;
@@ -53,6 +65,7 @@ public class ShutterButton extends ImageView {
public void setOnShutterButtonListener(OnShutterButtonListener listener) {
mListener = listener;
+ setOnLongClickListener(mLongClick);
}
@Override
@@ -66,6 +79,7 @@ public class ShutterButton extends ImageView {
public void enableTouch(boolean enable) {
mTouchEnabled = enable;
+ setLongClickable(enable);
}
/**
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 00bd8d1c4..49435e4c0 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -82,6 +82,12 @@ public class Storage {
public static Uri addImage(ContentResolver resolver, String title,
long date, Location location, int orientation, ExifInterface exif,
byte[] jpeg, int width, int height, String pictureFormat) {
+ int jpegLength = 0;
+
+ if (jpeg != null) {
+ jpegLength = jpeg.length;
+ }
+
// Save the image.
String path = generateFilepath(title, pictureFormat);
if (exif != null && (pictureFormat == null ||
@@ -91,7 +97,7 @@ public class Storage {
} catch (Exception e) {
Log.e(TAG, "Failed to write data", e);
}
- } else {
+ } else if (jpeg != null) {
if (!(pictureFormat.equalsIgnoreCase("jpeg") || pictureFormat == null)) {
File dir = new File(RAW_DIRECTORY);
dir.mkdirs();
@@ -99,7 +105,7 @@ public class Storage {
writeFile(path, jpeg);
}
return addImage(resolver, title, date, location, orientation,
- jpeg.length, path, width, height, pictureFormat);
+ jpegLength, path, width, height, pictureFormat);
}
// Add the image to media store.
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 3d748a97b..36e5862a2 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -648,6 +648,9 @@ public class VideoModule implements CameraModule,
mUI.setShutterPressed(pressed);
}
+ @Override
+ public void onShutterButtonLongClick() {}
+
private void qcomReadVideoPreferences() {
String videoEncoder = mPreferences.getString(
CameraSettings.KEY_VIDEO_ENCODER,
diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java
index 2a47d233e..02ce5516f 100644
--- a/src/com/android/camera/WideAnglePanoramaUI.java
+++ b/src/com/android/camera/WideAnglePanoramaUI.java
@@ -316,6 +316,9 @@ public class WideAnglePanoramaUI implements
}
@Override
+ public void onShutterButtonLongClick() {}
+
+ @Override
public void onLayoutChange(
View v, int l, int t, int r, int b,
int oldl, int oldt, int oldr, int oldb) {