diff options
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/AndroidCameraManagerImpl.java | 4 | ||||
-rw-r--r-- | src/com/android/camera/BestpictureActivity.java | 25 | ||||
-rw-r--r-- | src/com/android/camera/CameraSettings.java | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/CaptureModule.java | 102 | ||||
-rwxr-xr-x | src/com/android/camera/CaptureUI.java | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/MediaSaveService.java | 44 | ||||
-rw-r--r--[-rwxr-xr-x] | src/com/android/camera/PhotoModule.java | 4 | ||||
-rw-r--r-- | src/com/android/camera/SettingsManager.java | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/Storage.java | 12 | ||||
-rwxr-xr-x | src/com/android/camera/imageprocessor/PostProcessor.java | 140 | ||||
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/imageprocessor/ZSLQueue.java | 24 | ||||
-rwxr-xr-x | src/com/android/camera/imageprocessor/filter/BestpictureFilter.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/ui/CameraControls.java | 2 | ||||
-rwxr-xr-x | src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java | 64 |
14 files changed, 354 insertions, 84 deletions
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java index 438be2e90..4decaec6c 100644..100755 --- a/src/com/android/camera/AndroidCameraManagerImpl.java +++ b/src/com/android/camera/AndroidCameraManagerImpl.java @@ -293,7 +293,9 @@ class AndroidCameraManagerImpl implements CameraManager { try { mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); } catch (IOException e) { - throw new RuntimeException(e); + Log.d(TAG,"setPreviewDisplay failed, surface is destoried"); + if (errorCbInstance != null) + errorCbInstance.onStartPreviewFailure(msg.arg1); } return; diff --git a/src/com/android/camera/BestpictureActivity.java b/src/com/android/camera/BestpictureActivity.java index 45c45ed4b..cf285c2eb 100644 --- a/src/com/android/camera/BestpictureActivity.java +++ b/src/com/android/camera/BestpictureActivity.java @@ -48,6 +48,8 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.support.v4.app.FragmentActivity; import android.widget.CheckBox; import android.widget.PopupWindow; @@ -77,7 +79,12 @@ public class BestpictureActivity extends FragmentActivity { public static final String[] NAMES = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09" }; - + private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = + "android.media.action.STILL_IMAGE_CAMERA_SECURE"; + public static final String ACTION_IMAGE_CAPTURE_SECURE = + "android.media.action.IMAGE_CAPTURE_SECURE"; + public static final String SECURE_CAMERA_EXTRA = "secure_camera"; + private boolean mSecureCamera; public static final int NUM_IMAGES = 10; private ViewPager mImagePager; @@ -158,6 +165,22 @@ public class BestpictureActivity extends FragmentActivity { public void onCreate(Bundle state) { super.onCreate(state); mActivity = this; + Intent intent = getIntent(); + String action = intent.getAction(); + if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action) + || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) { + mSecureCamera = true; + } else { + mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false); + } + + if (mSecureCamera) { + // Change the window flags so that secure camera can show when locked + Window win = getWindow(); + WindowManager.LayoutParams params = win.getAttributes(); + params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; + win.setAttributes(params); + } mFilesPath = getFilesDir()+"/Bestpicture"; setContentView(R.layout.bestpicture_editor); Display display = getWindowManager().getDefaultDisplay(); diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 97c4eae0a..069fb8701 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -1027,10 +1027,6 @@ public class CameraSettings { return; } - if (numOfCameras > 2 ) { - numOfCameras = 2; - } - CharSequence[] entryValues = new CharSequence[numOfCameras]; for (int i = 0; i < numOfCameras; ++i) { entryValues[i] = "" + i; diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 84c1e6911..b06bd2d12 100644..100755 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -294,6 +294,7 @@ public class CaptureModule implements CameraModule, PhotoController, private Uri mSaveUri; private boolean mQuickCapture; private byte[] mJpegImageData; + private boolean mSaveRaw = false; /** * A {@link CameraCaptureSession } for camera preview. @@ -325,6 +326,7 @@ public class CaptureModule implements CameraModule, PhotoController, * An {@link ImageReader} that handles still image capture. */ private ImageReader[] mImageReader = new ImageReader[MAX_NUM_CAM]; + private ImageReader[] mRawImageReader = new ImageReader[MAX_NUM_CAM]; private NamedImages mNamedImages; private ContentResolver mContentResolver; private byte[] mLastJpegData; @@ -372,6 +374,7 @@ public class CaptureModule implements CameraModule, PhotoController, private MediaActionSound mSound; private Size mSupportedMaxPictureSize; + private Size mSupportedRawPictureSize; private class SelfieThread extends Thread { @@ -779,7 +782,7 @@ public class CaptureModule implements CameraModule, PhotoController, return false; } - private int getCameraMode() { + public int getCameraMode() { String value = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); if (value != null && value.equals(SettingsManager.SCENE_MODE_DUAL_STRING)) return DUAL_MODE; value = mSettingsManager.getValue(SettingsManager.KEY_MONO_ONLY); @@ -793,6 +796,12 @@ public class CaptureModule implements CameraModule, PhotoController, return isBackCamera() && getCameraMode() == DUAL_MODE && value.equals("on"); } + private boolean isRawCaptureOn() { + String value = mSettingsManager.getValue(SettingsManager.KEY_SAVERAW); + if (value == null) return false; + return value.equals("enable"); + } + private boolean isMpoOn() { String value = mSettingsManager.getValue(SettingsManager.KEY_MPO); if (value == null) return false; @@ -1068,10 +1077,16 @@ public class CaptureModule implements CameraModule, PhotoController, list.add(surs); } list.add(mImageReader[id].getSurface()); + if (mSaveRaw) { + list.add(mRawImageReader[id].getSurface()); + } if(mChosenImageFormat == ImageFormat.YUV_420_888 || mChosenImageFormat == ImageFormat.PRIVATE) { if (mPostProcessor.isZSLEnabled()) { mPreviewRequestBuilder[id].addTarget(mImageReader[id].getSurface()); list.add(mPostProcessor.getZSLReprocessImageReader().getSurface()); + if (mSaveRaw) { + mPreviewRequestBuilder[id].addTarget(mRawImageReader[id].getSurface()); + } mCameraDevice[id].createReprocessableCaptureSession(new InputConfiguration(mImageReader[id].getWidth(), mImageReader[id].getHeight(), mImageReader[id].getImageFormat()), list, captureSessionCallback, null); } else { @@ -1218,7 +1233,7 @@ public class CaptureModule implements CameraModule, PhotoController, mJpegImageData = data; } - public void showCapturedReview(byte[] jpegData, int orientation, boolean mirror) { + public void showCapturedReview(final byte[] jpegData, int orientation, boolean mirror) { mActivity.runOnUiThread(new Runnable() { @Override public void run() { @@ -1460,6 +1475,9 @@ public class CaptureModule implements CameraModule, PhotoController, checkAndPlayShutterSound(id); mCaptureSession[id].stopRepeating(); captureBuilder.addTarget(mImageReader[id].getSurface()); + if (mSaveRaw) { + captureBuilder.addTarget(mRawImageReader[id].getSurface()); + } mPostProcessor.onStartCapturing(); if(mPostProcessor.isManualMode()) { mPostProcessor.manualCapture(captureBuilder, mCaptureSession[id], mCaptureCallbackHandler); @@ -1469,6 +1487,9 @@ public class CaptureModule implements CameraModule, PhotoController, } } else { captureBuilder.addTarget(mImageReader[id].getSurface()); + if (mSaveRaw) { + captureBuilder.addTarget(mRawImageReader[id].getSurface()); + } mCaptureSession[id].stopRepeating(); if (mLongshotActive) { @@ -1667,19 +1688,24 @@ public class CaptureModule implements CameraModule, PhotoController, mImageReader[i] = ImageReader.newInstance(mPictureSize.getWidth(), mPictureSize.getHeight(), imageFormat, mPostProcessor.getMaxRequiredImageNum()); } + if (mSaveRaw) { + mRawImageReader[i] = ImageReader.newInstance(mSupportedRawPictureSize.getWidth(), + mSupportedRawPictureSize.getHeight(), ImageFormat.RAW10, mPostProcessor.getMaxRequiredImageNum()); + mPostProcessor.setRawImageReader(mRawImageReader[i]); + } mImageReader[i].setOnImageAvailableListener(mPostProcessor.getImageHandler(), mImageAvailableHandler); mPostProcessor.onImageReaderReady(mImageReader[i], mSupportedMaxPictureSize, mPictureSize); } else { mImageReader[i] = ImageReader.newInstance(mPictureSize.getWidth(), mPictureSize.getHeight(), imageFormat, PersistUtil.getLongshotShotLimit()); - mImageReader[i].setOnImageAvailableListener(new ImageAvailableListener(i) { + ImageAvailableListener listener = new ImageAvailableListener(i) { @Override public void onImageAvailable(ImageReader reader) { Log.d(TAG, "image available for cam: " + mCamId); Image image = reader.acquireNextImage(); - if(isMpoOn()) { + if (isMpoOn()) { mMpoSaveHandler.obtainMessage( MpoSaveHandler.MSG_NEW_IMG, mCamId, 0, image).sendToTarget(); } else { @@ -1691,32 +1717,44 @@ public class CaptureModule implements CameraModule, PhotoController, byte[] bytes = getJpegData(image); - ExifInterface exif = Exif.getExif(bytes); - int orientation = Exif.getOrientation(exif); - - if (getCameraMode() != CaptureModule.INTENT_MODE_NORMAL) { - mJpegImageData = bytes; - if (!mQuickCapture) { - showCapturedReview(bytes, orientation, - mPostProcessor.isSelfieMirrorOn()); - } else { - onCaptureDone(); - } + if (image.getFormat() == ImageFormat.RAW10) { + mActivity.getMediaSaveService().addRawImage(bytes, title, + "raw"); } else { - mActivity.getMediaSaveService().addImage(bytes, title, date, - null, image.getWidth(), image.getHeight(), orientation, null, - mOnMediaSavedListener, mContentResolver, "jpeg"); - - if(mLongshotActive) { - mLastJpegData = bytes; + ExifInterface exif = Exif.getExif(bytes); + int orientation = Exif.getOrientation(exif); + + if (getCameraMode() != CaptureModule.INTENT_MODE_NORMAL) { + mJpegImageData = bytes; + if (!mQuickCapture) { + showCapturedReview(bytes, orientation, + mPostProcessor.isSelfieMirrorOn()); + } else { + onCaptureDone(); + } } else { - mActivity.updateThumbnail(bytes); + mActivity.getMediaSaveService().addImage(bytes, title, date, + null, image.getWidth(), image.getHeight(), orientation, null, + mOnMediaSavedListener, mContentResolver, "jpeg"); + + if (mLongshotActive) { + mLastJpegData = bytes; + } else { + mActivity.updateThumbnail(bytes); + } } + image.close(); } - image.close(); } } - }, mImageAvailableHandler); + }; + mImageReader[i].setOnImageAvailableListener(listener, mImageAvailableHandler); + + if (mSaveRaw) { + mRawImageReader[i] = ImageReader.newInstance(mSupportedRawPictureSize.getWidth(), + mSupportedRawPictureSize.getHeight(), ImageFormat.RAW10, PersistUtil.getLongshotShotLimit()); + mRawImageReader[i].setOnImageAvailableListener(listener, mImageAvailableHandler); + } } } } @@ -2259,12 +2297,14 @@ public class CaptureModule implements CameraModule, PhotoController, if(flashMode != null && flashMode.equalsIgnoreCase("on")) { isFlashOn = true; } + + mSaveRaw = isRawCaptureOn(); if (scene != null) { int mode = Integer.parseInt(scene); Log.d(TAG, "Chosen postproc filter id : " + getPostProcFilterId(mode)); - mPostProcessor.onOpen(getPostProcFilterId(mode), isFlashOn, isTrackingFocusSettingOn(), isMakeupOn, isSelfieMirrorOn); + mPostProcessor.onOpen(getPostProcFilterId(mode), isFlashOn, isTrackingFocusSettingOn(), isMakeupOn, isSelfieMirrorOn, mSaveRaw); } else { - mPostProcessor.onOpen(PostProcessor.FILTER_NONE, isFlashOn, isTrackingFocusSettingOn(), isMakeupOn, isSelfieMirrorOn); + mPostProcessor.onOpen(PostProcessor.FILTER_NONE, isFlashOn, isTrackingFocusSettingOn(), isMakeupOn, isSelfieMirrorOn, mSaveRaw); } } if(mFrameProcessor != null) { @@ -2333,6 +2373,9 @@ public class CaptureModule implements CameraModule, PhotoController, setProModeVisible(); String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); + if (Integer.parseInt(scene) != SettingsManager.SCENE_MODE_UBIFOCUS_INT) { + setRefocusLastTaken(false); + } if(isPanoSetting(scene)) { if (mIntentMode != CaptureModule.INTENT_MODE_NORMAL) { mSettingsManager.setValue( @@ -2360,6 +2403,8 @@ public class CaptureModule implements CameraModule, PhotoController, if(mFrameProcessor != null){ mFrameProcessor.onDestory(); } + mSettingsManager.unregisterListener(this); + mSettingsManager.unregisterListener(mUI); } @Override @@ -2883,6 +2928,9 @@ public class CaptureModule implements CameraModule, PhotoController, Size[] prevSizes = mSettingsManager.getSupportedOutputSize(getMainCameraId(), SurfaceHolder.class); mSupportedMaxPictureSize = prevSizes[0]; + Size[] rawSize = mSettingsManager.getSupportedOutputSize(getMainCameraId(), + ImageFormat.RAW10); + mSupportedRawPictureSize = rawSize[0]; mPreviewSize = getOptimalPreviewSize(mPictureSize, prevSizes, screenSize.x, screenSize.y); Size[] thumbSizes = mSettingsManager.getSupportedThumbnailSizes(getMainCameraId()); mPictureThumbSize = getOptimalPreviewSize(mPictureSize, thumbSizes, 0, 0); // get largest thumb size @@ -4226,6 +4274,7 @@ public class CaptureModule implements CameraModule, PhotoController, updateVideoFlash(); return; case SettingsManager.KEY_FLASH_MODE: + case SettingsManager.KEY_SAVERAW: if (count == 0) restartSession(false); return; case SettingsManager.KEY_SCENE_MODE: @@ -4323,6 +4372,7 @@ public class CaptureModule implements CameraModule, PhotoController, onPauseAfterSuper(); onResumeBeforeSuper(); onResumeAfterSuper(); + setRefocusLastTaken(false); } public void restartSession(boolean isSurfaceChanged) { diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index 85d044eeb..2ef89abdf 100755 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -635,7 +635,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, } public void openSettingsMenu() { - if (mPreviewLayout.getVisibility() == View.VISIBLE) { + if (mPreviewLayout != null && mPreviewLayout.getVisibility() == View.VISIBLE) { return; } clearFocus(); @@ -1678,6 +1678,9 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, boolean changed = (width != mPreviewWidth) || (height != mPreviewHeight); mPreviewWidth = width; mPreviewHeight = height; + if (changed) { + showSurfaceView(); + } return changed; } diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java index 0daad1bab..2d7247d83 100644..100755 --- a/src/com/android/camera/MediaSaveService.java +++ b/src/com/android/camera/MediaSaveService.java @@ -134,6 +134,20 @@ public class MediaSaveService extends Service { t.execute(); } + public void addRawImage(final byte[] data, String title, String pictureFormat) { + if (isQueueFull()) { + Log.e(TAG, "Cannot add image when the queue is full"); + return; + } + RawImageSaveTask t = new RawImageSaveTask(data, title, pictureFormat); + + mMemoryUse += data.length; + if (isQueueFull()) { + onQueueFull(); + } + t.execute(); + } + public void addImage(final byte[] data, String title, long date, Location loc, int orientation, ExifInterface exif, OnMediaSavedListener l, ContentResolver resolver) { @@ -250,6 +264,36 @@ public class MediaSaveService extends Service { } } + private class RawImageSaveTask extends AsyncTask<Void, Void, Long> { + private byte[] data; + private String title; + private String pictureFormat; + + public RawImageSaveTask(byte[] data, String title, String pictureFormat) { + this.data = data; + this.title = title; + this.pictureFormat = pictureFormat; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + } + + @Override + protected Long doInBackground(Void... params) { + long length = Storage.addRawImage(title, data, pictureFormat); + return new Long(length); + } + + @Override + protected void onPostExecute(Long l) { + boolean previouslyFull = isQueueFull(); + mMemoryUse -= data.length; + if (isQueueFull() != previouslyFull) onQueueAvailable(); + } + } + private class ImageSaveTask extends AsyncTask <Void, Void, Uri> { private byte[] data; private String title; diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 860c29540..ecdae4dd3 100755..100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -4647,6 +4647,10 @@ public class PhotoModule mUI.setPreference(CameraSettings.KEY_ADVANCED_FEATURES, pref.getValue()); } + if (CameraSettings.KEY_ADVANCED_FEATURES.equals(pref.getKey())) { + mUI.setPreference(CameraSettings.KEY_QC_CHROMA_FLASH, pref.getValue()); + } + String ubiFocusOff = mActivity.getString(R.string. pref_camera_advanced_feature_value_ubifocus_off); String chromaFlashOff = mActivity.getString(R.string. diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index eadc322aa..638b89fb9 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -143,6 +143,8 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final String KEY_ANTI_BANDING_LEVEL = "pref_camera2_anti_banding_level_key"; public static final String KEY_HISTOGRAM = "pref_camera2_histogram_key"; public static final String KEY_HDR = "pref_camera2_hdr_key"; + public static final String KEY_SAVERAW = "pref_camera2_saveraw_key"; + private static final String TAG = "SnapCam_SettingsManager"; private static SettingsManager sInstance; diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java index 6239494dc..13f65e14c 100644..100755 --- a/src/com/android/camera/Storage.java +++ b/src/com/android/camera/Storage.java @@ -168,6 +168,18 @@ public class Storage { return insertImage(resolver, values); } + public static long addRawImage(String title, byte[] data, + String mimeType) { + String path = generateFilepath(title, mimeType); + int size = writeFile(path, data, null, mimeType); + // Try to get the real image size after add exif. + File f = new File(path); + if (f.exists() && f.isFile()) { + size = (int) f.length(); + } + return size; + } + // Overwrites the file and updates the MediaStore, or inserts the image if // one does not already exist. public static void updateImage(Uri imageUri, ContentResolver resolver, String title, long date, diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java index 73a0049d4..c64684f30 100755 --- a/src/com/android/camera/imageprocessor/PostProcessor.java +++ b/src/com/android/camera/imageprocessor/PostProcessor.java @@ -130,6 +130,7 @@ public class PostProcessor{ private ImageReader mImageReader; private ImageReader mZSLReprocessImageReader; private boolean mUseZSL = true; + private boolean mSaveRaw = false; private Handler mZSLHandler; private HandlerThread mZSLHandlerThread; private Handler mSavingHander; @@ -139,7 +140,7 @@ public class PostProcessor{ private TotalCaptureResult mZSLFallOffResult = null; private boolean mIsZSLFallOff = false; private TotalCaptureResult mLatestResultForLongShot = null; - private LinkedList<Image> mFallOffImages = new LinkedList<Image>(); + private LinkedList<ZSLQueue.ImageItem> mFallOffImages = new LinkedList<ZSLQueue.ImageItem>(); private int mPendingContinuousRequestCount = 0; public int mMaxRequiredImageNum; @@ -165,10 +166,18 @@ public class PostProcessor{ private class ImageWrapper { Image mImage; + Image mRawImage; boolean mIsTaken; public ImageWrapper(Image image) { mImage = image; + mRawImage = null; + mIsTaken = false; + } + + public ImageWrapper(Image image, Image rawImage) { + mImage = image; + mRawImage = rawImage; mIsTaken = false; } @@ -180,23 +189,31 @@ public class PostProcessor{ mIsTaken = true; return mImage; } + + public Image getRawImage() { + return mRawImage; + } } private void clearFallOffImage() { - for(Image im: mFallOffImages ) { + for(ZSLQueue.ImageItem item: mFallOffImages ) { try { - im.close(); + item.getImage().close(); + Image raw = item.getRawImage(); + if (raw != null) { + raw.close(); + } } catch(Exception e) { } } mFallOffImages.clear(); } - private Image findFallOffImage(long timestamp) { - Image foundImage = null; - for(Image im: mFallOffImages ) { - if(im.getTimestamp() == timestamp) { - foundImage = im; + private ZSLQueue.ImageItem findFallOffImage(long timestamp) { + ZSLQueue.ImageItem foundImage = null; + for(ZSLQueue.ImageItem item: mFallOffImages ) { + if(item.getImage().getTimestamp() == timestamp) { + foundImage = item; break; } } @@ -206,12 +223,16 @@ public class PostProcessor{ return foundImage; } - private void addFallOffImage(Image image) { - mFallOffImages.add(image); + private void addFallOffImage(ZSLQueue.ImageItem item) { + mFallOffImages.add(item); if(mFallOffImages.size() >= MAX_REQUIRED_IMAGE_NUM - 1) { - Image im = mFallOffImages.getFirst(); + ZSLQueue.ImageItem it = mFallOffImages.getFirst(); try { - im.close(); + it.getImage().close(); + Image raw = item.getRawImage(); + if (raw != null) { + raw.close(); + } } catch(Exception e) { } mFallOffImages.removeFirst(); @@ -220,6 +241,7 @@ public class PostProcessor{ class ImageHandlerTask implements Runnable, ImageReader.OnImageAvailableListener { private ImageWrapper mImageWrapper = null; + private ImageReader mRawImageReader = null; Semaphore mMutureLock = new Semaphore(1); @Override @@ -228,24 +250,42 @@ public class PostProcessor{ if(mUseZSL) { if(mController.isLongShotActive() && mPendingContinuousRequestCount > 0) { Image image = reader.acquireNextImage(); + Image rawImage = null; + if (mSaveRaw && mRawImageReader != null) { + rawImage = mRawImageReader.acquireNextImage(); + } ZSLQueue.ImageItem item = new ZSLQueue.ImageItem(); - item.setImage(image); + item.setImage(image, rawImage); if(onContinuousZSLImage(item, true)) { image.close(); + if (rawImage != null) { + rawImage.close(); + } } return; } if(mIsZSLFallOff) { Image image = reader.acquireNextImage(); + Image rawImage = null; + if (mSaveRaw && mRawImageReader != null) { + rawImage = mRawImageReader.acquireNextImage(); + } + ZSLQueue.ImageItem imageItem = new ZSLQueue.ImageItem(); + imageItem.setImage(image,rawImage); if(mZSLFallOffResult == null) { - addFallOffImage(image); + addFallOffImage(imageItem); return; } - addFallOffImage(image); - Image foundImage = findFallOffImage(mZSLFallOffResult.get(CaptureResult.SENSOR_TIMESTAMP).longValue()); - if(foundImage != null) { + addFallOffImage(imageItem); + ZSLQueue.ImageItem foundImage = findFallOffImage( + mZSLFallOffResult.get(CaptureResult.SENSOR_TIMESTAMP).longValue()); + if(foundImage != null && foundImage.getImage() != null) { Log.d(TAG,"ZSL fall off image is found"); - reprocessImage(foundImage, mZSLFallOffResult); + reprocessImage(foundImage.getImage(), mZSLFallOffResult); + Image raw = foundImage.getRawImage(); + if (raw != null) { + onRawImageToProcess(raw); + } mIsZSLFallOff = false; clearFallOffImage(); mZSLFallOffResult = null; @@ -256,18 +296,33 @@ public class PostProcessor{ } Image image = reader.acquireLatestImage(); + Image rawImage = null; + if (mSaveRaw && mRawImageReader != null) { + rawImage = mRawImageReader.acquireLatestImage(); + } + if (image == null) { return; } if (!mMutureLock.tryAcquire()) { image.close(); + if (rawImage != null) { + rawImage.close(); + } return; } if (mImageWrapper == null || mImageWrapper.isTaken()) { - mImageWrapper = new ImageWrapper(image); + if (mSaveRaw && rawImage != null) { + mImageWrapper = new ImageWrapper(image, rawImage); + } else { + mImageWrapper = new ImageWrapper(image); + } mMutureLock.release(); } else { image.close(); + if (rawImage != null) { + rawImage.close(); + } mMutureLock.release(); return; } @@ -276,8 +331,15 @@ public class PostProcessor{ } } else { //Non ZSL case Image image = reader.acquireNextImage(); + Image rawImage = null; if(image != null) { onImageToProcess(image); + if (mSaveRaw && mRawImageReader != null) { + rawImage = mRawImageReader.acquireNextImage(); + } + if (rawImage != null) { + onRawImageToProcess(rawImage); + } } } } catch (IllegalStateException e) { @@ -290,18 +352,27 @@ public class PostProcessor{ @Override public void run() { //Only ZSL case - Image image = mImageWrapper.getImage(); + Image image = mImageWrapper.getImage(); + Image rawImage = mImageWrapper.getRawImage(); try { mMutureLock.acquire(); if (mUseZSL) { if (mZSLQueue != null) { - mZSLQueue.add(image); + mZSLQueue.add(image, rawImage); } } mMutureLock.release(); } catch (InterruptedException e) { } } + + public void setRawImageReader(ImageReader rawImageReader) { + mRawImageReader = rawImageReader; + } + } + + public void setRawImageReader(ImageReader rawImageReader) { + mImageHandlerTask.setRawImageReader(rawImageReader); } public void onMetaAvailable(TotalCaptureResult metadata) { @@ -379,6 +450,9 @@ public class PostProcessor{ if (imageItem != null) { if(DEBUG_ZSL) Log.d(TAG,"Got the item from the queue"); reprocessImage(imageItem.getImage(), imageItem.getMetadata()); + if (mSaveRaw && imageItem.getRawImage() != null) { + onRawImageToProcess(imageItem.getRawImage()); + } return true; } else { if(DEBUG_ZSL) Log.d(TAG, "No good item in queue, register the request for the future"); @@ -397,11 +471,17 @@ public class PostProcessor{ if(isLongShotRequest) { if(mLatestResultForLongShot != null) { reprocessImage(imageItem.getImage(), mLatestResultForLongShot); + if (imageItem.getRawImage() != null) { + onRawImageToProcess(imageItem.getRawImage()); + } mPendingContinuousRequestCount--; return true; } } else { reprocessImage(imageItem.getImage(), imageItem.getMetadata()); + if (imageItem.getRawImage() != null) { + onRawImageToProcess(imageItem.getRawImage()); + } return true; } @@ -509,6 +589,17 @@ public class PostProcessor{ } } + private void onRawImageToProcess(Image image) { + ByteBuffer buffer = image.getPlanes()[0].getBuffer(); + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + long captureStartTime = System.currentTimeMillis(); + mNamedImages.nameNewImage(captureStartTime); + PhotoModule.NamedImages.NamedEntity name = mNamedImages.getNextNameEntity(); + String title = (name == null) ? null : name.title; + mActivity.getMediaSaveService().addRawImage(data, title, "raw"); + } + enum STATUS { DEINIT, INIT, @@ -574,12 +665,13 @@ public class PostProcessor{ return false; } - public void onOpen(int postFilterId, boolean isFlashModeOn, boolean isTrackingFocusOn, boolean isMakeupOn, boolean isSelfieMirrorOn) { + public void onOpen(int postFilterId, boolean isFlashModeOn, boolean isTrackingFocusOn, boolean isMakeupOn, boolean isSelfieMirrorOn, boolean isSaveRaw) { mImageHandlerTask = new ImageHandlerTask(); - + mSaveRaw = isSaveRaw; if(setFilter(postFilterId) || isFlashModeOn || isTrackingFocusOn || isMakeupOn || isSelfieMirrorOn || PersistUtil.getCameraZSLDisabled() - || SettingsManager.getInstance().isCamera2HDRSupport()) { + || SettingsManager.getInstance().isCamera2HDRSupport() + || mController.getCameraMode() == CaptureModule.DUAL_MODE) { mUseZSL = false; } else { mUseZSL = true; diff --git a/src/com/android/camera/imageprocessor/ZSLQueue.java b/src/com/android/camera/imageprocessor/ZSLQueue.java index f50858a35..b9dea4e51 100644..100755 --- a/src/com/android/camera/imageprocessor/ZSLQueue.java +++ b/src/com/android/camera/imageprocessor/ZSLQueue.java @@ -87,7 +87,7 @@ public class ZSLQueue { return -1; } - public void add(Image image) { + public void add(Image image, Image rawImage) { int lastIndex = -1; synchronized (mLock) { if(mBuffer == null) @@ -99,7 +99,7 @@ public class ZSLQueue { } if(mBuffer[mImageHead].getMetadata() != null) { if((mBuffer[mImageHead].getMetadata().get(CaptureResult.SENSOR_TIMESTAMP)).longValue() == image.getTimestamp()) { - mBuffer[mImageHead].setImage(image); + mBuffer[mImageHead].setImage(image,rawImage); lastIndex = mImageHead; mImageHead = (mImageHead + 1) % mBuffer.length; } else if((mBuffer[mImageHead].getMetadata().get(CaptureResult.SENSOR_TIMESTAMP)).longValue() > image.getTimestamp()) { @@ -107,17 +107,17 @@ public class ZSLQueue { } else { int i = findMeta(image.getTimestamp(), mImageHead); if(i == -1) { - mBuffer[mImageHead].setImage(image); + mBuffer[mImageHead].setImage(image, rawImage); mBuffer[mImageHead].setMetadata(null); mImageHead = (mImageHead + 1) % mBuffer.length; } else { lastIndex = mImageHead = i; - mBuffer[mImageHead].setImage(image); + mBuffer[mImageHead].setImage(image, rawImage); mImageHead = (mImageHead + 1) % mBuffer.length; } } } else { - mBuffer[mImageHead].setImage(image); + mBuffer[mImageHead].setImage(image, rawImage); lastIndex = mImageHead; mImageHead = (mImageHead + 1) % mBuffer.length; } @@ -156,7 +156,7 @@ public class ZSLQueue { } else { int i = findImage(timestamp, mMetaHead); if(i == -1) { - mBuffer[mMetaHead].setImage(null); + mBuffer[mMetaHead].setImage(null, null); mBuffer[mMetaHead].setMetadata(metadata); mMetaHead = (mMetaHead + 1) % mBuffer.length; } else { @@ -238,17 +238,24 @@ public class ZSLQueue { static class ImageItem { private Image mImage = null; + private Image mRawImage = null; private TotalCaptureResult mMetadata = null; public Image getImage() { return mImage; } - public void setImage(Image image) { + public Image getRawImage() {return mRawImage;} + + public void setImage(Image image, Image rawImage) { if(mImage != null) { mImage.close(); } + if(mRawImage != null) { + mRawImage.close(); + } mImage = image; + mRawImage =rawImage; } public TotalCaptureResult getMetadata() { @@ -263,6 +270,9 @@ public class ZSLQueue { if(mImage != null) { mImage.close(); } + if(mRawImage != null) { + mRawImage.close(); + } mImage = null; } diff --git a/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java b/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java index bf1852450..e2c784f97 100755 --- a/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java +++ b/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java @@ -74,7 +74,8 @@ public class BestpictureFilter implements ImageFilter { final String[] NAMES = {"00.jpg", "01.jpg", "02.jpg", "03.jpg", "04.jpg", "05.jpg", "06.jpg", "07.jpg", "08.jpg" ,"09.jpg"}; - + private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = + "android.media.action.STILL_IMAGE_CAMERA_SECURE"; private final static int TIME_DELAY = 50; private int mSavedCount = 0; private PhotoModule.NamedImages mNamedImages; @@ -214,6 +215,9 @@ public class BestpictureFilter implements ImageFilter { Log("Start best picture activity"); Intent intent = new Intent(); intent.setData(uri); + if (mActivity.isSecureCamera()) { + intent.setAction(INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); + } intent.setClass(mActivity, BestpictureActivity.class); mActivity.startActivityForResult(intent, BestpictureActivity.BESTPICTURE_ACTIVITY_CODE); } diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index b85d7f1ca..1e28080f4 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -244,8 +244,6 @@ public class CameraControls extends RotatableLayout { mFrontBackSwitcher.setEnabled(enable); if(TsMakeupManager.HAS_TS_MAKEUP) { mTsMakeupSwitcher.setEnabled(enable); - } else { - mHdrSwitcher.setEnabled(enable); } mPreview.setEnabled(enable); diff --git a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java index 944bf0800..b938363fa 100755 --- a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java +++ b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java @@ -29,7 +29,6 @@ package org.codeaurora.snapcam.filter; -import java.io.IOException; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayDeque; @@ -146,6 +145,7 @@ public class ClearSightImageProcessor { private boolean mDumpImages; private boolean mDumpYUV; private boolean mIsClosing; + private int mFinishReprocessNum; private static ClearSightImageProcessor mInstance; @@ -459,7 +459,7 @@ public class ClearSightImageProcessor { private ArrayDeque<Image> mMonoImages = new ArrayDeque<Image>( mNumBurstCount); - private SparseLongArray mReprocessingFrames = new SparseLongArray(); + private SparseLongArray[] mReprocessingFrames = new SparseLongArray[NUM_CAM]; private ArrayList<CaptureRequest> mReprocessingRequests = new ArrayList<CaptureRequest>(); private int mReprocessingPairCount; private int mReprocessedBayerCount; @@ -471,6 +471,8 @@ public class ClearSightImageProcessor { ImageProcessHandler(Looper looper) { super(looper); + mReprocessingFrames[CAM_TYPE_BAYER] = new SparseLongArray(); + mReprocessingFrames[CAM_TYPE_MONO] = new SparseLongArray(); } @Override @@ -480,6 +482,7 @@ public class ClearSightImageProcessor { switch (msg.what) { case MSG_START_CAPTURE: mCaptureDone = false; + mFinishReprocessNum = 0; mHasFailures = false; mReprocessingPairCount = 0; mReprocessedBayerCount = 0; @@ -516,7 +519,8 @@ public class ClearSightImageProcessor { Log.d(TAG, "handleTimeout"); releaseBayerFrames(); releaseMonoFrames(); - mReprocessingFrames.clear(); + mReprocessingFrames[CAM_TYPE_BAYER].clear(); + mReprocessingFrames[CAM_TYPE_MONO].clear(); mReprocessingRequests.clear(); removeMessages(MSG_NEW_CAPTURE_RESULT); @@ -536,10 +540,11 @@ public class ClearSightImageProcessor { } private void processImg(Message msg) { - Log.d(TAG, "processImg: " + msg.arg1); + int camId = msg.arg1; + Log.d(TAG, "processImg: " + camId); Image image = (Image) msg.obj; - if(mReprocessingFrames.size() > 0 - && mReprocessingFrames.indexOfValue(image.getTimestamp()) >= 0) { + if(mReprocessingFrames[camId].size() > 0 + && mReprocessingFrames[camId].indexOfValue(image.getTimestamp()) >= 0) { // reproc frame processNewReprocessImage(msg); } else { @@ -600,13 +605,31 @@ public class ClearSightImageProcessor { checkForValidFramePairAndReprocess(); } - Log.d(TAG, "processNewCaptureEvent - imagestoprocess[bayer] " + mNumImagesToProcess[CAM_TYPE_BAYER] + - " imagestoprocess[mono]: " + mNumImagesToProcess[CAM_TYPE_MONO]); + + Log.d(TAG, "processNewCaptureEvent - " + + "imagestoprocess[bayer] " + mNumImagesToProcess[CAM_TYPE_BAYER] + + " imagestoprocess[mono]: " + mNumImagesToProcess[CAM_TYPE_MONO] + + " mReprocessingPairCount: " + mReprocessingPairCount + + " mNumFrameCount: " + mNumFrameCount + + " mFinishReprocessNum: " + mFinishReprocessNum); + + if ((mNumImagesToProcess[CAM_TYPE_BAYER] == 0 + && mNumImagesToProcess[CAM_TYPE_MONO] == 0) + && mReprocessingPairCount != mNumFrameCount) { + while (!mBayerFrames.isEmpty() && !mMonoFrames.isEmpty() + && mReprocessingPairCount != mNumFrameCount) { + checkForValidFramePairAndReprocess(); + } + } if (mReprocessingPairCount == mNumFrameCount || (mNumImagesToProcess[CAM_TYPE_BAYER] == 0 && mNumImagesToProcess[CAM_TYPE_MONO] == 0)) { processFinalPair(); + if (mReprocessingPairCount != 0 && + mFinishReprocessNum == mReprocessingPairCount * 2) { + checkReprocessDone(); + } } } @@ -683,7 +706,7 @@ public class ClearSightImageProcessor { Long ts = Long.valueOf(reprocImg.mImage.getTimestamp()); Integer hash = ts.hashCode(); reprocRequest.setTag(hash); - mReprocessingFrames.put(hash, ts); + mReprocessingFrames[camId].put(hash, ts); Log.d(TAG, "sendReprocessRequest - adding reproc frame - hash: " + hash + ", ts: " + ts); mImageWriter[camId].queueInputImage(reprocImg.mImage); @@ -779,7 +802,8 @@ public class ClearSightImageProcessor { Image image = (Image) msg.obj; long ts = image.getTimestamp(); - Log.d(TAG, "processNewReprocessImage - cam: " + msg.arg1 + ", ts: " + ts); + int camId = msg.arg1; + Log.d(TAG, "processNewReprocessImage - cam: " + camId + ", ts: " + ts); int frameCount = isBayer?++mReprocessedBayerCount:++mReprocessedMonoCount; if(mDumpImages) { @@ -793,7 +817,7 @@ public class ClearSightImageProcessor { mClearsightRegisterHandler.obtainMessage(MSG_NEW_IMG, msg.arg1, 0, msg.obj).sendToTarget(); - mReprocessingFrames.removeAt(mReprocessingFrames.indexOfValue(ts)); + mReprocessingFrames[camId].removeAt(mReprocessingFrames[camId].indexOfValue(ts)); checkReprocessDone(); } @@ -809,24 +833,30 @@ public class ClearSightImageProcessor { Log.d(TAG, "reprocess - setReferenceResult: " + msg.obj); ClearSightNativeEngine.getInstance().setReferenceResult(isBayer, result); } - + mFinishReprocessNum++; checkReprocessDone(); } private void processNewReprocessFailure(Message msg) { - Log.d(TAG, "processNewReprocessFailure: " + msg.arg1); + int camId = msg.arg1; + Log.d(TAG, "processNewReprocessFailure: " + camId); CaptureFailure failure = (CaptureFailure)msg.obj; mReprocessingRequests.remove(failure.getRequest()); - mReprocessingFrames.delete(msg.arg2); + mReprocessingFrames[camId].delete(msg.arg2); mHasFailures = true; + mFinishReprocessNum++; checkReprocessDone(); } private void checkReprocessDone() { - Log.d(TAG, "checkReprocessDone capture done: " + mCaptureDone - + ", reproc frames: " + mReprocessingFrames.size()); + Log.d(TAG, "checkReprocessDone capture done: " + mCaptureDone + + ", reproc frames[bay]: " + mReprocessingFrames[CAM_TYPE_BAYER].size() + + ", reproc frames[mono]: " + mReprocessingFrames[CAM_TYPE_MONO].size() + + ", mReprocessingRequests: " + mReprocessingRequests.size()); // If all burst frames and results have been processed - if(mCaptureDone && mReprocessingFrames.size() == 0 && mReprocessingRequests.isEmpty()) { + if(mCaptureDone && mReprocessingFrames[CAM_TYPE_BAYER].size() == 0 + && mReprocessingFrames[CAM_TYPE_MONO].size() == 0 + && mReprocessingRequests.isEmpty()) { mClearsightRegisterHandler.obtainMessage(MSG_END_CAPTURE, mHasFailures?1:0, 0).sendToTarget(); removeMessages(MSG_NEW_REPROC_RESULT); removeMessages(MSG_NEW_REPROC_FAIL); |