From f54164331768ad54b35e9fe636f400c73988072e Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Mon, 25 Jul 2016 10:20:17 -0700 Subject: SnapdragonCamera: Saving MPO and DDM without CS Saving MPO and DDM without CS CRs-Fixed: 993611 Change-Id: Ie04bce460c57454b4cf57c88b47ef2a495b6e078 --- src/com/android/camera/CaptureModule.java | 125 ++++++++++++++++++++++++---- src/com/android/camera/CaptureUI.java | 1 + src/com/android/camera/SettingsManager.java | 3 + 3 files changed, 114 insertions(+), 15 deletions(-) (limited to 'src/com/android') diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 73d157f5a..b35da5d06 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -216,6 +216,7 @@ public class CaptureModule implements CameraModule, PhotoController, private HandlerThread mCameraThread; private HandlerThread mImageAvailableThread; private HandlerThread mCaptureCallbackThread; + private HandlerThread mMpoSaveThread; /** * A {@link Handler} for running tasks in the background. @@ -230,6 +231,7 @@ public class CaptureModule implements CameraModule, PhotoController, private Handler mCameraHandler; private Handler mImageAvailableHandler; private Handler mCaptureCallbackHandler; + private Handler mMpoSaveHandler; /** * An {@link ImageReader} that handles still image capture. @@ -608,6 +610,12 @@ public class CaptureModule implements CameraModule, PhotoController, return isBackCamera() && getCameraMode() == DUAL_MODE && value.equals("on"); } + private boolean isMpoOn() { + String value = mSettingsManager.getValue(SettingsManager.KEY_MPO); + if (value == null) return false; + return isBackCamera() && getCameraMode() == DUAL_MODE && value.equals("on"); + } + public static int getQualityNumber(String jpegQuality) { try { int qualityPercentile = Integer.parseInt(jpegQuality); @@ -1080,6 +1088,11 @@ public class CaptureModule implements CameraModule, PhotoController, } }, mCaptureCallbackHandler); } else { + if(isMpoOn()) { + mCaptureStartTime = System.currentTimeMillis(); + mMpoSaveHandler.obtainMessage(MpoSaveHandler.MSG_CONFIGURE, + Long.valueOf(mCaptureStartTime)).sendToTarget(); + } mCaptureSession[id].capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() { @@ -1275,21 +1288,25 @@ public class CaptureModule implements CameraModule, PhotoController, public void onImageAvailable(ImageReader reader) { Log.d(TAG, "image available for cam: " + mCamId); Image image = reader.acquireNextImage(); - mCaptureStartTime = System.currentTimeMillis(); - mNamedImages.nameNewImage(mCaptureStartTime); - NamedEntity name = mNamedImages.getNextNameEntity(); - String title = (name == null) ? null : name.title; - long date = (name == null) ? -1 : name.date; - - ByteBuffer buffer = image.getPlanes()[0].getBuffer(); - byte[] bytes = new byte[buffer.remaining()]; - mLastJpegData = bytes; - buffer.get(bytes); - - mActivity.getMediaSaveService().addImage(bytes, title, date, - null, image.getWidth(), image.getHeight(), 0, null, - mOnMediaSavedListener, mContentResolver, "jpeg"); - image.close(); + + if(isMpoOn()) { + mMpoSaveHandler.obtainMessage( + MpoSaveHandler.MSG_NEW_IMG, mCamId, 0, image).sendToTarget(); + } else { + mCaptureStartTime = System.currentTimeMillis(); + mNamedImages.nameNewImage(mCaptureStartTime); + NamedEntity name = mNamedImages.getNextNameEntity(); + String title = (name == null) ? null : name.title; + long date = (name == null) ? -1 : name.date; + + byte[] bytes = getJpegData(image); + mLastJpegData = bytes; + + mActivity.getMediaSaveService().addImage(bytes, title, date, + null, image.getWidth(), image.getHeight(), 0, null, + mOnMediaSavedListener, mContentResolver, "jpeg"); + image.close(); + } } }, mImageAvailableHandler); } @@ -1509,10 +1526,13 @@ public class CaptureModule implements CameraModule, PhotoController, mImageAvailableThread.start(); mCaptureCallbackThread = new HandlerThread("CameraCaptureCallback"); mCaptureCallbackThread.start(); + mMpoSaveThread = new HandlerThread("MpoSaveHandler"); + mMpoSaveThread.start(); mCameraHandler = new MyCameraHandler(mCameraThread.getLooper()); mImageAvailableHandler = new Handler(mImageAvailableThread.getLooper()); mCaptureCallbackHandler = new Handler(mCaptureCallbackThread.getLooper()); + mMpoSaveHandler = new MpoSaveHandler(mMpoSaveThread.getLooper()); } /** @@ -1522,6 +1542,7 @@ public class CaptureModule implements CameraModule, PhotoController, mCameraThread.quitSafely(); mImageAvailableThread.quitSafely(); mCaptureCallbackThread.quitSafely(); + mMpoSaveThread.quitSafely(); try { mCameraThread.join(); @@ -1544,6 +1565,13 @@ public class CaptureModule implements CameraModule, PhotoController, } catch (InterruptedException e) { e.printStackTrace(); } + try { + mMpoSaveThread.join(); + mMpoSaveThread = null; + mMpoSaveHandler = null; + } catch (InterruptedException e) { + e.printStackTrace(); + } } private void openCamera(int id) { @@ -3084,6 +3112,66 @@ public class CaptureModule implements CameraModule, PhotoController, } } + private class MpoSaveHandler extends Handler { + static final int MSG_CONFIGURE = 0; + static final int MSG_NEW_IMG = 1; + + private Image monoImage; + private Image bayerImage; + private Long captureStartTime; + + public MpoSaveHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_CONFIGURE: + captureStartTime = (Long) msg.obj; + break; + case MSG_NEW_IMG: + processNewImage(msg); + break; + } + } + + private void processNewImage(Message msg) { + Log.d(TAG, "MpoSaveHandler:processNewImage for cam id: " + msg.arg1); + if(msg.arg1 == MONO_ID) { + monoImage = (Image)msg.obj; + } else if(bayerImage == null){ + bayerImage = (Image)msg.obj; + } + + if(monoImage != null && bayerImage != null) { + saveMpoImage(); + } + } + + private void saveMpoImage() { + mNamedImages.nameNewImage(captureStartTime); + NamedEntity namedEntity = mNamedImages.getNextNameEntity(); + String title = (namedEntity == null) ? null : namedEntity.title; + long date = (namedEntity == null) ? -1 : namedEntity.date; + int width = bayerImage.getWidth(); + int height = bayerImage.getHeight(); + byte[] bayerBytes = getJpegData(bayerImage); + byte[] monoBytes = getJpegData(monoImage); + + mLastJpegData = bayerBytes; + mActivity.getMediaSaveService().addMpoImage( + null, bayerBytes, monoBytes, width, height, title, + date, null, 0, mOnMediaSavedListener, mContentResolver, "jpeg"); + + bayerImage.close(); + bayerImage = null; + monoImage.close(); + monoImage = null; + namedEntity = null; + } + } + @Override public void onClearSightSuccess() { Log.d(TAG, "onClearSightSuccess"); @@ -3137,4 +3225,11 @@ public class CaptureModule implements CameraModule, PhotoController, public void onErrorListener(int error) { enableRecordingLocation(false); } + + private byte[] getJpegData(Image image) { + ByteBuffer buffer = image.getPlanes()[0].getBuffer(); + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + return bytes; + } } diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index c07c3cf3e..9633f05e5 100644 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -104,6 +104,7 @@ public class CaptureUI implements SettingsManager.KEY_MONO_ONLY, SettingsManager.KEY_CLEARSIGHT, SettingsManager.KEY_MONO_PREVIEW, + SettingsManager.KEY_MPO, SettingsManager.KEY_NOISE_REDUCTION, SettingsManager.KEY_DIS, SettingsManager.KEY_VIDEO_ENCODER, diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index e78a3605b..971a22771 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -83,6 +83,7 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final String KEY_MONO_ONLY = "pref_camera2_mono_only_key"; public static final String KEY_MONO_PREVIEW = "pref_camera2_mono_preview_key"; public static final String KEY_CLEARSIGHT = "pref_camera2_clearsight_key"; + public static final String KEY_MPO = "pref_camera2_mpo_key"; public static final String KEY_FILTER_MODE = "pref_camera2_filter_mode_key"; public static final String KEY_COLOR_EFFECT = "pref_camera2_coloreffect_key"; public static final String KEY_SCENE_MODE = "pref_camera2_scenemode_key"; @@ -459,6 +460,7 @@ public class SettingsManager implements ListMenu.SettingsListener { ListPreference clearsight = mPreferenceGroup.findPreference(KEY_CLEARSIGHT); ListPreference monoPreview = mPreferenceGroup.findPreference(KEY_MONO_PREVIEW); ListPreference monoOnly = mPreferenceGroup.findPreference(KEY_MONO_ONLY); + ListPreference mpo = mPreferenceGroup.findPreference(KEY_MPO); ListPreference redeyeReduction = mPreferenceGroup.findPreference(KEY_REDEYE_REDUCTION); ListPreference videoQuality = mPreferenceGroup.findPreference(KEY_VIDEO_QUALITY); ListPreference videoEncoder = mPreferenceGroup.findPreference(KEY_VIDEO_ENCODER); @@ -510,6 +512,7 @@ public class SettingsManager implements ListMenu.SettingsListener { if (clearsight != null) removePreference(mPreferenceGroup, KEY_CLEARSIGHT); if (monoPreview != null) removePreference(mPreferenceGroup, KEY_MONO_PREVIEW); if (monoOnly != null) removePreference(mPreferenceGroup, KEY_MONO_ONLY); + if (mpo != null) removePreference(mPreferenceGroup, KEY_MPO); } if (redeyeReduction != null) { -- cgit v1.2.3