summaryrefslogtreecommitdiffstats
path: root/src/org/codeaurora/snapcam/filter/DDMNativeEngine.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/codeaurora/snapcam/filter/DDMNativeEngine.java')
-rw-r--r--src/org/codeaurora/snapcam/filter/DDMNativeEngine.java396
1 files changed, 396 insertions, 0 deletions
diff --git a/src/org/codeaurora/snapcam/filter/DDMNativeEngine.java b/src/org/codeaurora/snapcam/filter/DDMNativeEngine.java
new file mode 100644
index 000000000..b2b0a523d
--- /dev/null
+++ b/src/org/codeaurora/snapcam/filter/DDMNativeEngine.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2017, 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 org.codeaurora.snapcam.filter;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import android.graphics.Rect;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.util.Log;
+
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.TotalCaptureResult;
+
+import org.codeaurora.snapcam.filter.ClearSightNativeEngine.CamSystemCalibrationData;
+
+public class DDMNativeEngine {
+ private static final String TAG = "DDMNativeEngine";
+ static {
+ try {//load jni_dualcamera
+ System.loadLibrary("jni_dualcamera");
+ mLibLoaded = true;
+ Log.v(TAG, "successfully loaded jni_dualcamera lib");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(TAG, "failed to load jni_dualcamera lib");
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ mLibLoaded = false;
+ }
+
+ }
+
+ private CaptureResult.Key<byte[]> SCALE_CROP_ROTATION_REPROCESS_BLOB =
+ new CaptureResult.Key<byte[]>(
+ "org.codeaurora.qcamera3.hal_private_data.reprocess_data_blob",
+ byte[].class);
+
+ private static boolean mLibLoaded;
+ private Image mBayerImage;
+ private Image mMonoImage;
+ private ByteBuffer mPrimaryY;
+ private ByteBuffer mPrivaryVU;
+ CamReprocessInfo mBayerCamReprocessInfo;
+ CamReprocessInfo mMonoCamReprocessInfo;
+ CamSystemCalibrationData mCamSystemCalibrationData;
+ private float mLensFocusDistance;
+ private static final int Y_PLANE = 0;
+ private static final int VU_PLANE = 2;
+
+ public boolean getDepthMapSize(int[] depthMap){
+ return nativeGetDepthMapSize(mBayerImage.getWidth(), mBayerImage.getHeight(), depthMap);
+ }
+
+ public void setCamSystemCalibrationData(CamSystemCalibrationData otpCalibration){
+ mCamSystemCalibrationData = otpCalibration;
+ }
+
+ public String getOTPCalibration() {
+ return mCamSystemCalibrationData.toString();
+ }
+
+ public void reset() {
+ mBayerImage = null;
+ mMonoImage = null;
+ mBayerCamReprocessInfo = null;
+ mMonoCamReprocessInfo = null;
+ mLensFocusDistance = 0;
+ }
+ public boolean isReadyForGenerateDepth(){
+ return mBayerImage != null && mMonoImage != null
+ && mBayerCamReprocessInfo != null && mMonoCamReprocessInfo != null;
+ }
+
+ public void setBayerLensFocusDistance(float lensFocusDistance) {
+ mLensFocusDistance = lensFocusDistance;
+ }
+ public void setBayerImage(Image image){
+ mBayerImage = image;
+ }
+
+ public void setMonoImage(Image image) {
+ mMonoImage = image;
+ }
+
+ public void setBayerReprocessResult(CaptureResult result ){
+ byte[] bytes = result.get(SCALE_CROP_ROTATION_REPROCESS_BLOB);
+ mBayerCamReprocessInfo = CamReprocessInfo.createCamReprocessFromBytes(bytes);
+ }
+
+ public String getBayerScaleCrop() {
+ return mBayerCamReprocessInfo.toString();
+ }
+
+ public void setMonoReprocessResult(CaptureResult result) {
+ byte[] bytes = result.get(SCALE_CROP_ROTATION_REPROCESS_BLOB);
+ mMonoCamReprocessInfo = CamReprocessInfo.createCamReprocessFromBytes(bytes);
+ }
+
+ public String getMonoScaleCrop(){
+ return mMonoCamReprocessInfo.toString();
+ }
+
+ public boolean dualCameraGenerateDDM(byte[] depthMapBuffer, int depthMapStride, Rect roiRect) {
+ if ( mLensFocusDistance == 0 ){
+ Log.e(TAG, " dualCameraGenerateDDM error: mLensFocusDistance is 0");
+ return false;
+ }
+
+ if (mBayerImage == null || mMonoImage == null ) {
+ Log.e(TAG, "mBayerImage=" +(mBayerImage == null)+ " mMonoImage=" + (mMonoImage == null));
+ return false;
+ }
+
+ if ( depthMapBuffer == null ) {
+ Log.e(TAG, "depthMapBuffer can't be null");
+ return false;
+ }
+
+ if ( mMonoCamReprocessInfo== null
+ || mBayerCamReprocessInfo == null
+ || mCamSystemCalibrationData == null ) {
+ Log.e(TAG, "mMonoCamReprocessInfo== null:" +(mMonoCamReprocessInfo== null)
+ + " mBayerCamReprocessInfo == null:" +(mBayerCamReprocessInfo == null)
+ + " mCamSystemCalibrationData == null:" +(mCamSystemCalibrationData == null));
+ return false;
+ }
+
+ Plane[] bayerPlanes = mBayerImage.getPlanes();
+ Plane[] monoPlanes = mMonoImage.getPlanes();
+ int[] goodRoi = new int[4];
+ boolean result = nativeDualCameraGenerateDDM(
+ bayerPlanes[Y_PLANE].getBuffer(),
+ bayerPlanes[VU_PLANE].getBuffer(),
+ mBayerImage.getWidth(),
+ mBayerImage.getHeight(),
+ bayerPlanes[Y_PLANE].getRowStride(),
+ bayerPlanes[VU_PLANE].getRowStride(),
+
+ monoPlanes[Y_PLANE].getBuffer(),
+ monoPlanes[VU_PLANE].getBuffer(),
+ mMonoImage.getWidth(),
+ mMonoImage.getHeight(),
+ monoPlanes[Y_PLANE].getRowStride(),
+ monoPlanes[VU_PLANE].getRowStride(),
+
+ depthMapBuffer,
+ depthMapStride,
+
+ goodRoi,
+
+ mBayerCamReprocessInfo.toString(),
+ mMonoCamReprocessInfo.toString(),
+ mCamSystemCalibrationData.toString(),
+ mLensFocusDistance,
+ true);
+ roiRect.left = goodRoi[0];
+ roiRect.top = goodRoi[1];
+ roiRect.right = goodRoi[0] + goodRoi[2];
+ roiRect.bottom = goodRoi[1] + goodRoi[3];
+
+ return result;
+ }
+
+
+
+ private native boolean nativeGetDepthMapSize(int primaryWidth, int primaryHeight,int[] size);
+
+ private native boolean nativeDualCameraGenerateDDM(
+ ByteBuffer primaryY,
+ ByteBuffer primaryVU,
+ int primaryWidth,
+ int primaryHeight,
+ int primaryStrideY,
+ int primaryStrideVU,
+
+ ByteBuffer auxiliaryY,
+ ByteBuffer auxiliaryVU,
+ int auxiliaryWidth,
+ int auxiliaryHeight,
+ int auxiliaryStrideY,
+ int auxiliaryStrideVU,
+
+ byte[] outDst,
+ int dstStride,
+
+ int[] roiRect,
+
+ String scaleCropRotationDataPrimaryCamera,
+ String scaleCropRotationDataAuxiliaryCamera,
+ String otpCalibration,
+ float focalLengthPrimaryCamera,
+ boolean isAuxiliaryMonoSensor);
+
+ public static class DepthMap{
+ private int width;
+ private int height;
+ private ByteBuffer buffer;
+ private int stride;
+ private Rect roi;
+ }
+ public static class CamStreamCropInfo{
+ int stream_id;
+ Rect crop;
+ Rect roi_map;
+
+ private CamStreamCropInfo(){}
+
+ public static CamStreamCropInfo createFromBytes(byte[] bytes) {
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ return createFromByteBuffer(buffer);
+ }
+
+ public static CamStreamCropInfo createFromByteBuffer(ByteBuffer buffer) {
+ CamStreamCropInfo camStreamCropInfo = new CamStreamCropInfo();
+ camStreamCropInfo.stream_id = buffer.getInt();
+ Rect crop = new Rect();
+ crop.left = buffer.getInt();
+ crop.top = buffer.getInt();
+ crop.right = crop.left + buffer.getInt();
+ crop.bottom = crop.top + buffer.getInt();
+ camStreamCropInfo.crop = crop;
+
+ Rect roi_map = new Rect();
+ roi_map.left = buffer.getInt();
+ roi_map.top = buffer.getInt();
+ roi_map.right = roi_map.left + buffer.getInt();
+ roi_map.bottom = roi_map.top + buffer.getInt();
+ camStreamCropInfo.roi_map = roi_map;
+
+ return camStreamCropInfo;
+ }
+ }
+
+ public static class CamRotationInfo {
+ int jpeg_rotation;
+ int device_rotation;
+ int stream_id;
+ private CamRotationInfo(){}
+
+ public static CamRotationInfo createCamReprocessFromBytes(byte[] bytes) {
+ ByteBuffer buf = ByteBuffer.wrap(bytes);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ return createFromByteBuffer(buf);
+ }
+ public static CamRotationInfo createFromByteBuffer(ByteBuffer buffer) {
+ CamRotationInfo rotation_info = new CamRotationInfo();
+ rotation_info.jpeg_rotation = buffer.getInt();
+ rotation_info.device_rotation = buffer.getInt();
+ rotation_info.stream_id = buffer.getInt();
+ return rotation_info;
+ }
+ }
+ public static class CamReprocessInfo{
+ CamStreamCropInfo sensor_crop_info;
+ CamStreamCropInfo camif_crop_info;
+ CamStreamCropInfo isp_crop_info;
+ CamStreamCropInfo cpp_crop_info;
+ float af_focal_length_ratio;
+ int pipeline_flip;
+ CamRotationInfo rotation_info;
+
+ private final String SCALE_CROP_ROTATION_FORMAT_STRING[] = {
+ "Sensor Crop left = %d\n",
+ "Sensor Crop top = %d\n",
+ "Sensor Crop width = %d\n",
+ "Sensor Crop height = %d\n",
+ "Sensor ROI Map left = %d\n",
+ "Sensor ROI Map top = %d\n",
+ "Sensor ROI Map width = %d\n",
+ "Sensor ROI Map height = %d\n",
+ "CAMIF Crop left = %d\n",
+ "CAMIF Crop top = %d\n",
+ "CAMIF Crop width = %d\n",
+ "CAMIF Crop height = %d\n",
+ "CAMIF ROI Map left = %d\n",
+ "CAMIF ROI Map top = %d\n",
+ "CAMIF ROI Map width = %d\n",
+ "CAMIF ROI Map height = %d\n",
+ "ISP Crop left = %d\n",
+ "ISP Crop top = %d\n",
+ "ISP Crop width = %d\n",
+ "ISP Crop height = %d\n",
+ "ISP ROI Map left = %d\n",
+ "ISP ROI Map top = %d\n",
+ "ISP ROI Map width = %d\n",
+ "ISP ROI Map height = %d\n",
+ "CPP Crop left = %d\n",
+ "CPP Crop top = %d\n",
+ "CPP Crop width = %d\n",
+ "CPP Crop height = %d\n",
+ "CPP ROI Map left = %d\n",
+ "CPP ROI Map top = %d\n",
+ "CPP ROI Map width = %d\n",
+ "CPP ROI Map height = %d\n",
+ "Focal length Ratio = %f\n",
+ "Current pipeline mirror flip setting = %d\n",
+ "Current pipeline rotation setting = %d\n"
+ };
+
+ public static CamReprocessInfo createCamReprocessFromBytes(byte[] bytes){
+ ByteBuffer buf = ByteBuffer.wrap(bytes);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ return createCamReprocessFromBytes(buf);
+ }
+ public static CamReprocessInfo createCamReprocessFromBytes(ByteBuffer buffer){
+ CamReprocessInfo scaleCropRotation = new CamReprocessInfo();
+ scaleCropRotation.sensor_crop_info = CamStreamCropInfo.createFromByteBuffer(buffer);
+ scaleCropRotation.camif_crop_info = CamStreamCropInfo.createFromByteBuffer(buffer);
+ scaleCropRotation.isp_crop_info = CamStreamCropInfo.createFromByteBuffer(buffer);
+ scaleCropRotation.cpp_crop_info = CamStreamCropInfo.createFromByteBuffer(buffer);
+ scaleCropRotation.af_focal_length_ratio = buffer.getFloat();
+ scaleCropRotation.pipeline_flip = buffer.getInt();
+ scaleCropRotation.rotation_info = CamRotationInfo.createFromByteBuffer(buffer);
+ return scaleCropRotation;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[0], this.sensor_crop_info.crop.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[1], this.sensor_crop_info.crop.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[2], this.sensor_crop_info.crop.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[3], this.sensor_crop_info.crop.height()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[4], this.sensor_crop_info.roi_map.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[5], this.sensor_crop_info.roi_map.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[6], this.sensor_crop_info.roi_map.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[7], this.sensor_crop_info.roi_map.height()));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[8], this.camif_crop_info.crop.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[9], this.camif_crop_info.crop.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[10], this.camif_crop_info.crop.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[11], this.camif_crop_info.crop.height()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[12], this.camif_crop_info.roi_map.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[13], this.camif_crop_info.roi_map.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[14], this.camif_crop_info.roi_map.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[15], this.camif_crop_info.roi_map.height()));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[16], this.isp_crop_info.crop.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[17], this.isp_crop_info.crop.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[18], this.isp_crop_info.crop.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[19], this.isp_crop_info.crop.height()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[20], this.isp_crop_info.roi_map.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[21], this.isp_crop_info.roi_map.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[22], this.isp_crop_info.roi_map.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[23], this.isp_crop_info.roi_map.height()));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[24], this.cpp_crop_info.crop.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[25], this.cpp_crop_info.crop.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[26], this.cpp_crop_info.crop.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[27], this.cpp_crop_info.crop.height()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[28], this.cpp_crop_info.roi_map.left));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[29], this.cpp_crop_info.roi_map.top));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[30], this.cpp_crop_info.roi_map.width()));
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[31], this.cpp_crop_info.roi_map.height()));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[32], this.af_focal_length_ratio));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[33], this.pipeline_flip));
+
+ sb.append(String.format(SCALE_CROP_ROTATION_FORMAT_STRING[34], this.rotation_info.jpeg_rotation));
+ return sb.toString();
+ }
+
+ }
+
+
+} \ No newline at end of file