QCamera2: Restart ZSL preview in longshot if needed

 Due to recent buffer count optimizations
 ZSL might run with considerably less buffers
 during longshot mode. Preview needs to
 restart in this case so that the intended
 number of buffers could get allocated.

Change-Id: I251ab7fabff46dd9ff322167b3fdbd4a9f8f23ef
diff --git a/QCamera2/HAL/QCamera2HWI.cpp b/QCamera2/HAL/QCamera2HWI.cpp
index 2c75042..1554a57 100644
--- a/QCamera2/HAL/QCamera2HWI.cpp
+++ b/QCamera2/HAL/QCamera2HWI.cpp
@@ -2901,16 +2901,48 @@
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
-int QCamera2HardwareInterface::sendCommand(int32_t command, int32_t /*arg1*/, int32_t /*arg2*/)
+int QCamera2HardwareInterface::sendCommand(int32_t command,
+        int32_t &arg1, int32_t &/*arg2*/)
 {
     int rc = NO_ERROR;
 
     switch (command) {
     case CAMERA_CMD_LONGSHOT_ON:
+        arg1 = 0;
         // Longshot can only be enabled when image capture
         // is not active.
         if ( !m_stateMachine.isCaptureRunning() ) {
             mLongshotEnabled = true;
+
+            // Due to recent buffer count optimizations
+            // ZSL might run with considerably less buffers
+            // when not in longshot mode. Preview needs to
+            // restart in this case.
+            if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
+                QCameraChannel *pChannel = NULL;
+                QCameraStream *pSnapStream = NULL;
+                pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
+                if (NULL != pChannel) {
+                    QCameraStream *pStream = NULL;
+                    for(int i = 0; i < pChannel->getNumOfStreams(); i++) {
+                        pStream = pChannel->getStreamByIndex(i);
+                        if (pStream != NULL) {
+                            if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
+                                pSnapStream = pStream;
+                                break;
+                            }
+                        }
+                    }
+                    if (NULL != pSnapStream) {
+                        uint8_t required = 0;
+                        required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
+                        if (pSnapStream->getBufferCount() < required) {
+                            arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
+                        }
+                    }
+                }
+            }
+            //
         } else {
             rc = NO_INIT;
         }
diff --git a/QCamera2/HAL/QCamera2HWI.h b/QCamera2/HAL/QCamera2HWI.h
index 6018c8b..38734ab 100644
--- a/QCamera2/HAL/QCamera2HWI.h
+++ b/QCamera2/HAL/QCamera2HWI.h
@@ -292,7 +292,7 @@
     int cancelLiveSnapshot();
     char* getParameters();
     int putParameters(char *);
-    int sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+    int sendCommand(int32_t cmd, int32_t &arg1, int32_t &arg2);
     int release();
     int dump(int fd);
     int registerFaceImage(void *img_ptr,
diff --git a/QCamera2/HAL/QCameraStateMachine.cpp b/QCamera2/HAL/QCameraStateMachine.cpp
index 39f89e1..1e70149 100644
--- a/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/QCamera2/HAL/QCameraStateMachine.cpp
@@ -1156,6 +1156,21 @@
             rc = m_parent->sendCommand(cmd_payload->cmd,
                                        cmd_payload->arg1,
                                        cmd_payload->arg2);
+            if (CAMERA_CMD_LONGSHOT_ON == cmd_payload->cmd) {
+                if (QCAMERA_SM_EVT_RESTART_PERVIEW == cmd_payload->arg1) {
+                    m_parent->stopPreview();
+                    // Clear memory pools
+                    m_parent->m_memoryPool.clear();
+                    // start preview again
+                    rc = m_parent->preparePreview();
+                    if (rc == NO_ERROR) {
+                        rc = m_parent->startPreview();
+                        if (rc != NO_ERROR) {
+                            m_parent->unpreparePreview();
+                        }
+                    }
+                }
+            }
             result.status = rc;
             result.request_api = evt;
             result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
diff --git a/QCamera2/HAL/QCameraStateMachine.h b/QCamera2/HAL/QCameraStateMachine.h
index eb164c2..8f3879f 100644
--- a/QCamera2/HAL/QCameraStateMachine.h
+++ b/QCamera2/HAL/QCameraStateMachine.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundataion. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -86,6 +86,7 @@
     QCAMERA_SM_EVT_SNAPSHOT_DONE,            // internal evt that snapshot is done
     QCAMERA_SM_EVT_THERMAL_NOTIFY,           // evt notify from thermal daemon
     QCAMERA_SM_EVT_STOP_CAPTURE_CHANNEL,     // stop capture channel
+    QCAMERA_SM_EVT_RESTART_PERVIEW,          // internal preview restart
     QCAMERA_SM_EVT_MAX
 } qcamera_sm_evt_enum_t;
 
diff --git a/QCamera2/HAL/QCameraStream.h b/QCamera2/HAL/QCameraStream.h
index 20ba32b..f7838bc 100644
--- a/QCamera2/HAL/QCameraStream.h
+++ b/QCamera2/HAL/QCameraStream.h
@@ -100,6 +100,8 @@
     bool isDeffered() const { return mDefferedAllocation; }
     void deleteStream();
 
+    uint8_t getBufferCount() { return mNumBufs; }
+
     int mDumpFrame;
     int mDumpMetaFrame;
     int mDumpSkipCnt;