summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Yoo <jyoo@codeaurora.org>2016-08-25 11:17:57 -0700
committerJay Wang <jaywang@codeaurora.org>2016-09-27 15:54:53 -0700
commitda315cfe9dcff36827dcf3cbaff53d823a4d228b (patch)
tree0ccf641d03ce3369b6475b8f369919b49bc745d5
parent7dd609bbc372c2bbeb9e3c10fe567e085da4f15d (diff)
downloadandroid_packages_apps_Snap-da315cfe9dcff36827dcf3cbaff53d823a4d228b.tar.gz
android_packages_apps_Snap-da315cfe9dcff36827dcf3cbaff53d823a4d228b.tar.bz2
android_packages_apps_Snap-da315cfe9dcff36827dcf3cbaff53d823a4d228b.zip
SnapdragonCamera: Chromaflash Filter
Adding Chromaflash Filter for Camera2 Change-Id: I04b399abe26a3fdcdc91240036a683711b21f8a8 CRs-Fixed: 1067848
-rw-r--r--res/drawable-hdpi/chroma_flash.pngbin0 -> 1534 bytes
-rw-r--r--res/values/camera2arrays.xml3
-rw-r--r--res/values/qcomstrings.xml1
-rw-r--r--src/com/android/camera/CaptureModule.java23
-rw-r--r--src/com/android/camera/SettingsManager.java3
-rw-r--r--src/com/android/camera/imageprocessor/PostProcessor.java7
-rw-r--r--src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java194
7 files changed, 230 insertions, 1 deletions
diff --git a/res/drawable-hdpi/chroma_flash.png b/res/drawable-hdpi/chroma_flash.png
new file mode 100644
index 000000000..97cdc790d
--- /dev/null
+++ b/res/drawable-hdpi/chroma_flash.png
Binary files differ
diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml
index 453627b2c..f4c17d6c4 100644
--- a/res/values/camera2arrays.xml
+++ b/res/values/camera2arrays.xml
@@ -134,6 +134,7 @@
<item>9</item>
<item>-1</item>
<item>103</item>
+ <item>105</item>
<item>104</item>
</string-array>
@@ -156,6 +157,7 @@
<item>@string/pref_camera_scenemode_entry_snow</item>
<item>@string/pref_camera_scenemode_entry_asd</item>
<item>@string/pref_camera_scenemode_entry_bestpicture</item>
+ <item>@string/pref_camera_scenemode_entry_chromaflash</item>
<item>@string/pref_camera_scenemode_entry_panorama</item>
</string-array>
@@ -177,6 +179,7 @@
<item>@drawable/snow</item>
<item>@drawable/ic_scene_mode_smartauto</item>
<item>@drawable/pick_the_best_photo</item>
+ <item>@drawable/chroma_flash</item>
<item>@drawable/scene_panorama</item>
</array>
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index c27ec976a..04bebfc16 100644
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -1024,6 +1024,7 @@
<string name="pref_camera2_videosnap_entry_disable" translatable="true">Disable</string>
<string name="pref_camera2_trackingfocus_title" translatable="true">Tracking Focus</string>
<string name="pref_camera_scenemode_entry_bestpicture" translatable="true">BestPicture</string>
+ <string name="pref_camera_scenemode_entry_chromaflash" translatable="true">ChromaFlash</string>
<string name="pref_camera_scenemode_entry_panorama" translatable="true">Panorama</string>
<string name="bestpicture_done" translatable="true">DONE</string>
<string name="bestpicture_at_least_one_picture" translatable="true">At least, one picture has to be chosen.</string>
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 69cdecfc5..8b1e24723 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -76,6 +76,7 @@ import android.widget.Toast;
import com.android.camera.exif.ExifInterface;
import com.android.camera.Exif;
+import com.android.camera.imageprocessor.filter.ChromaflashFilter;
import com.android.camera.imageprocessor.filter.ImageFilter;
import com.android.camera.imageprocessor.PostProcessor;
import com.android.camera.imageprocessor.FrameProcessor;
@@ -922,6 +923,26 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ public void setFlashModeToPreview(int id, boolean isFlashOn) {
+ Log.d(TAG, "setFlashModeToPreview " + isFlashOn);
+ if(isFlashOn) {
+ mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+ mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
+ } else {
+ mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+ mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
+ }
+ applyAFRegions(mPreviewRequestBuilder[id], id);
+ applyAERegions(mPreviewRequestBuilder[id], id);
+ mPreviewRequestBuilder[id].setTag(id);
+ try {
+ mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
public void setFocusDistanceToPreview(int id, float fd) {
mPreviewRequestBuilder[id].set(CaptureRequest.LENS_FOCUS_DISTANCE, fd);
mPreviewRequestBuilder[id].setTag(id);
@@ -1810,6 +1831,8 @@ public class CaptureModule implements CameraModule, PhotoController,
return PostProcessor.FILTER_OPTIZOOM;
} else if (mode == SettingsManager.SCENE_MODE_NIGHT_INT && SharpshooterFilter.isSupportedStatic()) {
return PostProcessor.FILTER_SHARPSHOOTER;
+ } else if (mode == SettingsManager.SCENE_MODE_CHROMAFLASH_INT && ChromaflashFilter.isSupportedStatic()) {
+ return PostProcessor.FILTER_CHROMAFLASH;
} else if (mode == SettingsManager.SCENE_MODE_UBIFOCUS_INT) {
return PostProcessor.FILTER_UBIFOCUS;
}// else if (mode == SettingsManager.SCENE_MODE_AUTO_INT && StillmoreFilter.isSupportedStatic()) {
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 20fbc2173..b97964039 100644
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -47,6 +47,7 @@ import android.util.Size;
import com.android.camera.imageprocessor.filter.BeautificationFilter;
import com.android.camera.imageprocessor.filter.BestpictureFilter;
+import com.android.camera.imageprocessor.filter.ChromaflashFilter;
import com.android.camera.imageprocessor.filter.OptizoomFilter;
import com.android.camera.imageprocessor.filter.TrackingFocusFrameListener;
import com.android.camera.imageprocessor.filter.UbifocusFilter;
@@ -82,6 +83,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final int SCENE_MODE_UBIFOCUS_INT = 102;
public static final int SCENE_MODE_BESTPICTURE_INT = 103;
public static final int SCENE_MODE_PANORAMA_INT = 104;
+ public static final int SCENE_MODE_CHROMAFLASH_INT = 105;
public static final String SCENE_MODE_DUAL_STRING = "100";
public static final String KEY_CAMERA_SAVEPATH = "pref_camera2_savepath_key";
public static final String KEY_RECORD_LOCATION = "pref_camera2_recordlocation_key";
@@ -1022,6 +1024,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
if (UbifocusFilter.isSupportedStatic() && cameraId == CaptureModule.BAYER_ID) modes.add(SCENE_MODE_UBIFOCUS_INT + "");
if (BestpictureFilter.isSupportedStatic() && cameraId == CaptureModule.BAYER_ID) modes.add(SCENE_MODE_BESTPICTURE_INT + "");
if (PanoCaptureProcessView.isSupportedStatic() && cameraId == CaptureModule.BAYER_ID) modes.add(SCENE_MODE_PANORAMA_INT + "");
+ if (ChromaflashFilter.isSupportedStatic()) modes.add(SCENE_MODE_CHROMAFLASH_INT + "");
for (int mode : sceneModes) {
modes.add("" + mode);
}
diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java
index 817ea246d..72ac30fb9 100644
--- a/src/com/android/camera/imageprocessor/PostProcessor.java
+++ b/src/com/android/camera/imageprocessor/PostProcessor.java
@@ -58,6 +58,7 @@ import com.android.camera.PhotoModule;
import com.android.camera.SettingsManager;
import com.android.camera.exif.ExifInterface;
import com.android.camera.imageprocessor.filter.BestpictureFilter;
+import com.android.camera.imageprocessor.filter.ChromaflashFilter;
import com.android.camera.imageprocessor.filter.OptizoomFilter;
import com.android.camera.imageprocessor.filter.SharpshooterFilter;
import com.android.camera.imageprocessor.filter.StillmoreFilter;
@@ -87,7 +88,8 @@ public class PostProcessor{
public static final int FILTER_UBIFOCUS = 3;
public static final int FILTER_STILLMORE = 4;
public static final int FILTER_BESTPICTURE = 5;
- public static final int FILTER_MAX = 6;
+ public static final int FILTER_CHROMAFLASH = 6;
+ public static final int FILTER_MAX = 7;
//BestPicture requires 10 which is the biggest among filters
public static final int MAX_REQUIRED_IMAGE_NUM = 11;
@@ -508,6 +510,9 @@ public class PostProcessor{
case FILTER_BESTPICTURE:
mFilter = new BestpictureFilter(mController, mActivity);
break;
+ case FILTER_CHROMAFLASH:
+ mFilter = new ChromaflashFilter(mController);
+ break;
}
}
diff --git a/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java b/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java
new file mode 100644
index 000000000..4f54eb108
--- /dev/null
+++ b/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java
@@ -0,0 +1,194 @@
+/*
+Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.camera.imageprocessor.filter;
+
+import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.camera.CaptureModule;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChromaflashFilter implements ImageFilter{
+ public static final int NUM_REQUIRED_IMAGE = 3;
+ private int mWidth;
+ private int mHeight;
+ private int mStrideY;
+ private int mStrideVU;
+ private static String TAG = "ChromaflashFilter";
+ private static final boolean DEBUG = false;
+ private static boolean mIsSupported = false;
+ private ByteBuffer mOutBuf;
+ private CaptureModule mModule;
+ private int mImageNum = -1;
+
+ private static void Log(String msg) {
+ if(DEBUG) {
+ Log.d(TAG, msg);
+ }
+ }
+ public ChromaflashFilter(CaptureModule module) {
+ mModule = module;
+ }
+
+ @Override
+ public List<CaptureRequest> setRequiredImages(CaptureRequest.Builder builder) {
+ return null;
+ }
+
+ @Override
+ public String getStringName() {
+ return TAG;
+ }
+
+ @Override
+ public int getNumRequiredImage() {
+ return NUM_REQUIRED_IMAGE;
+ }
+
+ @Override
+ public void init(int width, int height, int strideY, int strideVU) {
+ Log("init");
+ mWidth = width/2*2;
+ mHeight = height/2*2;
+ mStrideY = strideY/2*2;
+ mStrideVU = strideVU/2*2;
+ mOutBuf = ByteBuffer.allocate(mStrideY*mHeight*3/2);
+ mImageNum = -1;
+ Log("width: "+mWidth+" height: "+mHeight+" strideY: "+mStrideY+" strideVU: "+mStrideVU);
+ nativeInit(mWidth, mHeight, mStrideY, mStrideVU,
+ 0, 0, mWidth, mHeight, NUM_REQUIRED_IMAGE);
+ }
+
+ @Override
+ public void deinit() {
+ Log("deinit");
+ mOutBuf = null;
+ mImageNum = -1;
+ nativeDeinit();
+ }
+
+ @Override
+ public void addImage(ByteBuffer bY, ByteBuffer bVU, int imageNum, Object param) {
+ Log("addImage");
+ int yActualSize = bY.remaining();
+ int vuActualSize = bVU.remaining();
+ mImageNum = imageNum;
+ int status = nativeAddImage(bY, bVU, yActualSize, vuActualSize, imageNum);
+ if(status != 0) {
+ Log.e(TAG, "Fail to add image");
+ }
+ }
+
+ @Override
+ public ResultImage processImage() {
+ Log("processImage ");
+ int[] roi = new int[4];
+ int status = nativeProcessImage(mOutBuf.array(), roi);
+ Log("processImage done");
+ mImageNum = -1;
+ if(status < 0) { //In failure case, library will return the first image as it is.
+ Log.w(TAG, "Fail to process the image.");
+ }
+ return new ResultImage(mOutBuf, new Rect(roi[0], roi[1], roi[0]+roi[2], roi[1] + roi[3]), mWidth, mHeight, mStrideY);
+ }
+
+ @Override
+ public boolean isSupported() {
+ return mIsSupported;
+ }
+
+ @Override
+ public boolean isFrameListener() {
+ return false;
+ }
+
+ @Override
+ public boolean isManualMode() {
+ return true;
+ }
+
+ @Override
+ public void manualCapture(CaptureRequest.Builder builder, CameraCaptureSession captureSession,
+ CameraCaptureSession.CaptureCallback callback, Handler handler) throws CameraAccessException {
+ for(int i=0; i < NUM_REQUIRED_IMAGE; i++) {
+ if(i == 1) {
+ waitTillGetImage(0);
+ mModule.setFlashModeToPreview(mModule.getMainCameraId(), true);
+ builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+ builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
+ } else {
+ if(i == 2) {
+ waitTillGetImage(1);
+ }
+ mModule.setFlashModeToPreview(mModule.getMainCameraId(), false);
+ builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+ builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
+ }
+ captureSession.capture(builder.build(), callback, handler);
+ }
+ }
+
+ private void waitTillGetImage(int imageNum) {
+ while(mImageNum < imageNum) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public static boolean isSupportedStatic() {
+ return mIsSupported;
+ }
+
+ private native int nativeInit(int width, int height, int yStride, int vuStride,
+ int roiX, int roiY, int roiW, int roiH, int numImages);
+ private native int nativeDeinit();
+ private native int nativeAddImage(ByteBuffer yB, ByteBuffer vuB, int ySize, int vuSize, int imageNum);
+ private native int nativeProcessImage(byte[] buffer, int[] roi);
+
+ static {
+ try {
+ System.loadLibrary("jni_chromaflash");
+ mIsSupported = true;
+ }catch(UnsatisfiedLinkError e) {
+ Log.d(TAG, e.toString());
+ mIsSupported = false;
+ }
+ }
+}