QCamera2: Adds support for NV16 snapshots

- This change adds support for image capture using
  NV16 pixelformat. This pixelformat will be added
  to the supported list of picture formats if the
  capabilities include it and can be configured by
  the camera client.

Change-Id: Ica7859c00601ea32f2a96691b9502744fa2e70ca
diff --git a/camera/QCamera2/HAL/QCamera2HWI.cpp b/camera/QCamera2/HAL/QCamera2HWI.cpp
index 365eb0f..076ca94 100644
--- a/camera/QCamera2/HAL/QCamera2HWI.cpp
+++ b/camera/QCamera2/HAL/QCamera2HWI.cpp
@@ -1922,7 +1922,8 @@
         delChannel(QCAMERA_CH_TYPE_PREVIEW);
 
         // start snapshot
-        if (mParameters.isJpegPictureFormat()) {
+        if (mParameters.isJpegPictureFormat() ||
+            mParameters.isNV16PictureFormat() ) {
             rc = addCaptureChannel();
             if (rc == NO_ERROR) {
                 // start postprocessor
@@ -1991,7 +1992,8 @@
         }
     } else {
         // normal capture case
-        if (mParameters.isJpegPictureFormat()) {
+        if (mParameters.isJpegPictureFormat() ||
+            mParameters.isNV16PictureFormat() ) {
             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
             delChannel(QCAMERA_CH_TYPE_CAPTURE);
         } else {
diff --git a/camera/QCamera2/HAL/QCameraParameters.cpp b/camera/QCamera2/HAL/QCameraParameters.cpp
index 0ef70c7..5ebabb3 100644
--- a/camera/QCamera2/HAL/QCameraParameters.cpp
+++ b/camera/QCamera2/HAL/QCameraParameters.cpp
@@ -312,6 +312,7 @@
 
 const QCameraParameters::QCameraMap QCameraParameters::PICTURE_TYPES_MAP[] = {
     {PIXEL_FORMAT_JPEG,                          CAM_FORMAT_JPEG},
+    {PIXEL_FORMAT_YUV422SP,                      CAM_FORMAT_YUV_422_NV16},
     {QC_PIXEL_FORMAT_YUV_RAW_8BIT_YUYV,          CAM_FORMAT_YUV_RAW_8BIT_YUYV},
     {QC_PIXEL_FORMAT_YUV_RAW_8BIT_YVYU,          CAM_FORMAT_YUV_RAW_8BIT_YVYU},
     {QC_PIXEL_FORMAT_YUV_RAW_8BIT_UYVY,          CAM_FORMAT_YUV_RAW_8BIT_UYVY},
@@ -4726,7 +4727,11 @@
         format = mPreviewFormat;
         break;
     case CAM_STREAM_TYPE_SNAPSHOT:
-        format = CAM_FORMAT_YUV_420_NV21;
+        if ( mPictureFormat == CAM_FORMAT_YUV_422_NV16 ) {
+            format = CAM_FORMAT_YUV_422_NV16;
+        } else {
+            format = CAM_FORMAT_YUV_420_NV21;
+        }
         break;
     case CAM_STREAM_TYPE_VIDEO:
         format = CAM_FORMAT_YUV_420_NV12;
@@ -4812,7 +4817,6 @@
                                                cam_dimension_t &dim)
 {
     int32_t ret = NO_ERROR;
-
     memset(&dim, 0, sizeof(cam_dimension_t));
 
     switch (streamType) {
diff --git a/camera/QCamera2/HAL/QCameraParameters.h b/camera/QCamera2/HAL/QCameraParameters.h
index a3bd9f6..c62ecac 100644
--- a/camera/QCamera2/HAL/QCameraParameters.h
+++ b/camera/QCamera2/HAL/QCameraParameters.h
@@ -407,6 +407,7 @@
     int32_t setNumOfSnapshot();
     int32_t adjustPreviewFpsRange(cam_fps_range_t *fpsRange);
     bool isJpegPictureFormat() {return (mPictureFormat == CAM_FORMAT_JPEG);};
+    bool isNV16PictureFormat() {return (mPictureFormat == CAM_FORMAT_YUV_422_NV16);};
     cam_denoise_process_type_t getWaveletDenoiseProcessPlate();
     int32_t getLiveSnapshotSize(cam_dimension_t &dim) {dim = m_LiveSnapshotSize; return NO_ERROR;};
     int getFlipMode(cam_stream_type_t streamType);
diff --git a/camera/QCamera2/HAL/QCameraPostProc.cpp b/camera/QCamera2/HAL/QCameraPostProc.cpp
index e08cc72..88c2722 100644
--- a/camera/QCamera2/HAL/QCameraPostProc.cpp
+++ b/camera/QCamera2/HAL/QCameraPostProc.cpp
@@ -468,6 +468,8 @@
         ALOGD("%s: need reprocess", __func__);
         // enqueu to post proc input queue
         m_inputPPQ.enqueue((void *)frame);
+    } else if (m_parent->mParameters.isNV16PictureFormat()) {
+        processRawData(frame);
     } else {
         ALOGD("%s: no need offline reprocess, sending to jpeg encoding", __func__);
         qcamera_jpeg_data_t *jpeg_job =
@@ -1100,7 +1102,19 @@
 {
     int32_t rc = NO_ERROR;
 
-    mm_camera_buf_def_t *frame = recvd_frame->bufs[0];
+    mm_camera_buf_def_t *frame = NULL;
+    for ( int i= 0 ; i < recvd_frame->num_bufs ; i++ ) {
+        if ( recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT ||
+             recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW ) {
+            frame = recvd_frame->bufs[i];
+            break;
+        }
+    }
+    if ( NULL == frame ) {
+        ALOGE("%s: No valid raw buffer", __func__);
+        return BAD_VALUE;
+    }
+
     QCameraMemory *rawMemObj = (QCameraMemory *)frame->mem_info;
     camera_memory_t *raw_mem = NULL;
 
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
index e7c115c..d3b1c12 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -1601,6 +1601,9 @@
     case CAM_FORMAT_YUV_420_YV12:
         val= V4L2_PIX_FMT_NV12;
         break;
+    case CAM_FORMAT_YUV_422_NV16:
+        val= V4L2_PIX_FMT_NV16;
+        break;
     default:
         val = 0;
         CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt);