Merge "SnapdragonCamera: Fix compile error on Android M" into camera.lnx.1.0-dev.1.0
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
old mode 100644
new mode 100755
index 572ae95..11046e2
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -54,6 +54,10 @@
android:taskAffinity="com.android.camera.CameraActivity"
android:theme="@style/Theme.Camera"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
<meta-data
android:name="com.android.keyguard.layout"
diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml
index 204638c..efa9b20 100644
--- a/res/values/camera2arrays.xml
+++ b/res/values/camera2arrays.xml
@@ -1030,4 +1030,15 @@
<item>@string/pref_camera2_auto_hdr_entry_enable</item>
<item>@string/pref_camera2_auto_hdr_entry_disable</item>
</string-array>
+
+ <string-array name="pref_camera2_saveraw_entries" translatable="false">
+ <item>@string/pref_camera2_saveraw_entry_disable</item>
+ <item>@string/pref_camera2_saveraw_entry_enable</item>
+ </string-array>
+
+ <string-array name="pref_camera2_saveraw_entryvalues" translatable="false">
+ <item>@string/pref_camera2_saveraw_value_disable</item>
+ <item>@string/pref_camera2_saveraw_value_enable</item>
+ </string-array>
+
</resources>
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index 70b211d..baf472c 100644
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -1050,6 +1050,14 @@
<string name="pref_camera2_timer_value_2sec" translatable="false">2</string>
<string name="pref_camera2_timer_value_5sec" translatable="false">5</string>
<string name="pref_camera2_timer_value_10sec" translatable="false">10</string>
+ <string name="pref_camera2_saveraw_default">disable</string>
+ <string name="pref_camera2_saveraw_title">Save with RAW format</string>
+ <string name="pref_camera2_saveraw_value_disable" translatable="false">disable</string>
+ <string name="pref_camera2_saveraw_value_enable" translatable="false">enable</string>
+
+ <string name="pref_camera2_saveraw_entry_disable">disable</string>
+ <string name="pref_camera2_saveraw_entry_enable">enable</string>
+
<string name="panocapture_direction_is_not_determined" translatable="true">Move constantly in one direciton.</string>
<string name="panocapture_intro" translatable="true">Press camera button to start.</string>
<string name="panocapture_direction_is_changed" translatable="true">Direction is changed. Stopping now...</string>
diff --git a/res/xml/capture_preferences.xml b/res/xml/capture_preferences.xml
index 6789397..8dd3eb7 100644
--- a/res/xml/capture_preferences.xml
+++ b/res/xml/capture_preferences.xml
@@ -335,4 +335,11 @@
camera:entryValues="@array/pref_camera2_hdr_entryvalues"
camera:key="pref_camera2_hdr_key"
camera:title="@string/pref_camera2_hdr_title" />
+
+ <ListPreference
+ camera:key="pref_camera2_saveraw_key"
+ camera:defaultValue="@string/pref_camera2_saveraw_default"
+ camera:title="@string/pref_camera2_saveraw_title"
+ camera:entries="@array/pref_camera2_saveraw_entries"
+ camera:entryValues="@array/pref_camera2_saveraw_entryvalues" />
</PreferenceGroup>
diff --git a/res/xml/setting_menu_preferences.xml b/res/xml/setting_menu_preferences.xml
index f09ca87..d781310 100644
--- a/res/xml/setting_menu_preferences.xml
+++ b/res/xml/setting_menu_preferences.xml
@@ -275,7 +275,7 @@
android:summary="Version"
android:title="Version Info" />
</PreferenceCategory>
-
+
<PreferenceCategory
android:key="developer"
android:layout="@layout/preferences_category"
@@ -329,5 +329,14 @@
android:layout="@layout/preference"
android:summary="%s"
android:title="@string/pref_camera2_auto_hdr_title" />
+
+ <ListPreference
+ android:defaultValue="@string/pref_camera2_saveraw_default"
+ android:entries="@array/pref_camera2_saveraw_entries"
+ android:entryValues="@array/pref_camera2_saveraw_entryvalues"
+ android:key="pref_camera2_saveraw_key"
+ android:layout="@layout/preference"
+ android:summary="%s"
+ android:title="@string/pref_camera2_saveraw_title" />
</PreferenceCategory>
</PreferenceScreen>
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 97c4eae..069fb87 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -1027,10 +1027,6 @@
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 36251aa..33fd686 100755
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -294,6 +294,7 @@
private Uri mSaveUri;
private boolean mQuickCapture;
private byte[] mJpegImageData;
+ private boolean mSaveRaw = false;
/**
* A {@link CameraCaptureSession } for camera preview.
@@ -325,6 +326,7 @@
* 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 @@
private MediaActionSound mSound;
private Size mSupportedMaxPictureSize;
+ private Size mSupportedRawPictureSize;
private class SelfieThread extends Thread {
@@ -777,7 +780,7 @@
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);
@@ -791,6 +794,12 @@
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;
@@ -1066,10 +1075,16 @@
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 {
@@ -1458,6 +1473,9 @@
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);
@@ -1467,6 +1485,9 @@
}
} else {
captureBuilder.addTarget(mImageReader[id].getSurface());
+ if (mSaveRaw) {
+ captureBuilder.addTarget(mRawImageReader[id].getSurface());
+ }
mCaptureSession[id].stopRepeating();
if (mLongshotActive) {
@@ -1665,19 +1686,24 @@
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 {
@@ -1689,32 +1715,44 @@
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");
+ ExifInterface exif = Exif.getExif(bytes);
+ int orientation = Exif.getOrientation(exif);
- if(mLongshotActive) {
- mLastJpegData = bytes;
+ 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);
+ }
}
}
}
@@ -2257,12 +2295,14 @@
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) {
@@ -2331,6 +2371,9 @@
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(
@@ -2358,6 +2401,8 @@
if(mFrameProcessor != null){
mFrameProcessor.onDestory();
}
+ mSettingsManager.unregisterListener(this);
+ mSettingsManager.unregisterListener(mUI);
}
@Override
@@ -2881,6 +2926,9 @@
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
@@ -4224,6 +4272,7 @@
updateVideoFlash();
return;
case SettingsManager.KEY_FLASH_MODE:
+ case SettingsManager.KEY_SAVERAW:
if (count == 0) restartSession(false);
return;
case SettingsManager.KEY_SCENE_MODE:
@@ -4321,6 +4370,7 @@
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 8bbbf17..e8c3c6b 100755
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -624,7 +624,7 @@
}
public void openSettingsMenu() {
- if (mPreviewLayout.getVisibility() == View.VISIBLE) {
+ if (mPreviewLayout != null && mPreviewLayout.getVisibility() == View.VISIBLE) {
return;
}
clearFocus();
@@ -1665,6 +1665,9 @@
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
old mode 100644
new mode 100755
index 0daad1b..2d7247d
--- a/src/com/android/camera/MediaSaveService.java
+++ b/src/com/android/camera/MediaSaveService.java
@@ -134,6 +134,20 @@
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 @@
}
}
+ 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/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 3ce6460..f553c60 100644
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -143,6 +143,8 @@
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
old mode 100644
new mode 100755
index 6239494..13f65e1
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -168,6 +168,18 @@
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 73a0049..c64684f 100755
--- a/src/com/android/camera/imageprocessor/PostProcessor.java
+++ b/src/com/android/camera/imageprocessor/PostProcessor.java
@@ -130,6 +130,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
class ImageHandlerTask implements Runnable, ImageReader.OnImageAvailableListener {
private ImageWrapper mImageWrapper = null;
+ private ImageReader mRawImageReader = null;
Semaphore mMutureLock = new Semaphore(1);
@Override
@@ -228,24 +250,42 @@
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 @@
}
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 @@
}
} 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 @@
@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 @@
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 @@
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 @@
}
}
+ 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 @@
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
old mode 100644
new mode 100755
index f50858a..b9dea4e
--- a/src/com/android/camera/imageprocessor/ZSLQueue.java
+++ b/src/com/android/camera/imageprocessor/ZSLQueue.java
@@ -87,7 +87,7 @@
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 @@
}
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 @@
} 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 @@
} 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 @@
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 @@
if(mImage != null) {
mImage.close();
}
+ if(mRawImage != null) {
+ mRawImage.close();
+ }
mImage = null;
}
diff --git a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
index 944bf08..b938363 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 @@
private boolean mDumpImages;
private boolean mDumpYUV;
private boolean mIsClosing;
+ private int mFinishReprocessNum;
private static ClearSightImageProcessor mInstance;
@@ -459,7 +459,7 @@
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 @@
ImageProcessHandler(Looper looper) {
super(looper);
+ mReprocessingFrames[CAM_TYPE_BAYER] = new SparseLongArray();
+ mReprocessingFrames[CAM_TYPE_MONO] = new SparseLongArray();
}
@Override
@@ -480,6 +482,7 @@
switch (msg.what) {
case MSG_START_CAPTURE:
mCaptureDone = false;
+ mFinishReprocessNum = 0;
mHasFailures = false;
mReprocessingPairCount = 0;
mReprocessedBayerCount = 0;
@@ -516,7 +519,8 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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);