Merge "QCamera2:Adding logs for calculating AF time"
diff --git a/QCamera2/HAL/QCameraPostProc.cpp b/QCamera2/HAL/QCameraPostProc.cpp
index f05fefa..0f7753a 100644
--- a/QCamera2/HAL/QCameraPostProc.cpp
+++ b/QCamera2/HAL/QCameraPostProc.cpp
@@ -780,6 +780,11 @@
             free(app_cb->release_data.frame);
             app_cb->release_data.frame = NULL;
         }
+        if (app_cb && NULL != app_cb->release_data.streamBufs) {
+            app_cb->release_data.streamBufs->deallocate();
+            delete app_cb->release_data.streamBufs;
+            app_cb->release_data.streamBufs = NULL;
+        }
         free(app_cb);
     }
 }
@@ -1152,6 +1157,18 @@
         raw_mem = rawMemObj->getMemory(frame->buf_idx, false);
     }
 
+    QCameraChannel *pChannel = m_parent->getChannelByHandle(recvd_frame->ch_id);
+    if ( NULL == pChannel ) {
+        ALOGE("%s: Invalid channel", __func__);
+        return BAD_VALUE;
+    }
+
+    QCameraStream *pStream = pChannel->getStreamByHandle(frame->stream_id);
+    if ( NULL == pStream ) {
+        ALOGE("%s: Invalid stream", __func__);
+        return BAD_VALUE;
+    }
+
     if (NULL != rawMemObj && NULL != raw_mem) {
         // dump frame into file
         m_parent->dumpFrameToFile(frame->buffer, frame->frame_len,
@@ -1183,12 +1200,15 @@
             m_parent->msgTypeEnabledWithLock(CAMERA_MSG_COMPRESSED_IMAGE) > 0) {
             qcamera_release_data_t release_data;
             memset(&release_data, 0, sizeof(qcamera_release_data_t));
-            release_data.frame = recvd_frame;
-            sendDataNotify(CAMERA_MSG_COMPRESSED_IMAGE,
-                           raw_mem,
-                           0,
-                           NULL,
-                           &release_data);
+            release_data.streamBufs = rawMemObj;
+            rc = sendDataNotify(CAMERA_MSG_COMPRESSED_IMAGE,
+                                raw_mem,
+                                0,
+                                NULL,
+                                &release_data);
+            if ( NO_ERROR == rc ) {
+                pStream->acquireStreamBufs();
+            }
         }
     } else {
         ALOGE("%s: Cannot get raw mem", __func__);
diff --git a/QCamera2/HAL/QCameraPostProc.h b/QCamera2/HAL/QCameraPostProc.h
index 230f6df..391afd2 100644
--- a/QCamera2/HAL/QCameraPostProc.h
+++ b/QCamera2/HAL/QCameraPostProc.h
@@ -65,6 +65,7 @@
 typedef struct {
     camera_memory_t *        data;     // ptr to data memory struct
     mm_camera_super_buf_t *  frame;    // ptr to frame
+    QCameraMemory *          streamBufs; //ptr to stream buffers
 } qcamera_release_data_t;
 
 typedef struct {
diff --git a/QCamera2/HAL/QCameraStream.cpp b/QCamera2/HAL/QCameraStream.cpp
index 7acff1d..20dfcb3 100644
--- a/QCamera2/HAL/QCameraStream.cpp
+++ b/QCamera2/HAL/QCameraStream.cpp
@@ -169,7 +169,8 @@
         mStreamInfoBuf(NULL),
         mStreamBufs(NULL),
         mAllocator(allocator),
-        mBufDefs(NULL)
+        mBufDefs(NULL),
+        mStreamBufsAcquired(false)
 {
     mMemVtbl.user_data = this;
     mMemVtbl.get_bufs = get_bufs;
@@ -666,8 +667,10 @@
     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
                      // mm-camera-interface own the buffer, so no need to free
     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
-    mStreamBufs->deallocate();
-    delete mStreamBufs;
+    if ( !mStreamBufsAcquired ) {
+        mStreamBufs->deallocate();
+        delete mStreamBufs;
+    }
 
     return rc;
 }
@@ -864,6 +867,24 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : acquireStreamBufs
+ *
+ * DESCRIPTION: acquire stream buffers and postpone their release.
+ *
+ * PARAMETERS : None
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::acquireStreamBufs()
+{
+    mStreamBufsAcquired = true;
+
+    return NO_ERROR;
+}
+
+/*===========================================================================
  * FUNCTION   : mapBuf
  *
  * DESCRIPTION: map stream related buffer to backend server
diff --git a/QCamera2/HAL/QCameraStream.h b/QCamera2/HAL/QCameraStream.h
index ab2e2f7..dabff26 100644
--- a/QCamera2/HAL/QCameraStream.h
+++ b/QCamera2/HAL/QCameraStream.h
@@ -79,6 +79,7 @@
     QCameraMemory *getStreamBufs() {return mStreamBufs;};
     uint32_t getMyServerID();
     cam_stream_type_t getMyType();
+    int32_t acquireStreamBufs();
 
     int32_t mapBuf(uint8_t buf_type, uint32_t buf_idx,
                    int32_t plane_idx, int fd, uint32_t size);
@@ -107,6 +108,7 @@
     cam_padding_info_t mPaddingInfo;
     cam_rect_t mCropInfo;
     pthread_mutex_t mCropLock; // lock to protect crop info
+    bool mStreamBufsAcquired;
 
     static int32_t get_bufs(
                      cam_frame_len_offset_t *offset,
diff --git a/QCamera2/HAL/test/qcamera_test.cpp b/QCamera2/HAL/test/qcamera_test.cpp
index 52c5415..49d423b 100644
--- a/QCamera2/HAL/test/qcamera_test.cpp
+++ b/QCamera2/HAL/test/qcamera_test.cpp
@@ -501,6 +501,7 @@
     mCamera.clear();
     mHardwareActive = false;
     mPreviewRunning = false;
+    mRecordRunning = false;
 
     return NO_ERROR;
 }
@@ -540,6 +541,7 @@
             return ret;
         }
 
+        mParams.set("recording-hint", "true");
         mParams.setPreviewSize(previewWidth, previewHeight);
         mParams.setPictureSize(currentPictureSize.width, currentPictureSize.height);
 
@@ -623,6 +625,52 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : startRecording
+ *
+ * DESCRIPTION: triggers start recording
+ *
+ * PARAMETERS : None
+ *
+ * RETURN     : status_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+status_t CameraContext::startRecording()
+{
+    status_t ret = NO_ERROR;
+
+    if ( mPreviewRunning ) {
+        ret = mCamera->startRecording();
+        mRecordRunning = true;
+    }
+
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : stopRecording
+ *
+ * DESCRIPTION: triggers start recording
+ *
+ * PARAMETERS : None
+ *
+ * RETURN     : status_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+status_t CameraContext::stopRecording()
+{
+    status_t ret = NO_ERROR;
+
+    if ( mRecordRunning ) {
+        mCamera->stopRecording();
+        mRecordRunning = false;
+    }
+
+    return ret;
+}
+
+/*===========================================================================
  * FUNCTION   : stopPreview
  *
  * DESCRIPTION: stops camera preview
@@ -818,6 +866,10 @@
            CHANGE_PREVIEW_SIZE_CMD,
            currentPreviewSize.width,
            currentPreviewSize.height);
+    printf("   %c. Start Recording\n",
+            START_RECORD_CMD);
+    printf("   %c. Stop Recording\n",
+            STOP_RECORD_CMD);
     printf("   %c. Enable preview frames\n",
             ENABLE_PRV_CALLBACKS_CMD);
     printf("   %c. Trigger autofocus \n",
@@ -924,6 +976,18 @@
         }
         break;
 
+    case START_RECORD_CMD:
+        {
+            stat = currentCamera->startRecording();
+        }
+        break;
+
+    case STOP_RECORD_CMD:
+        {
+            stat = currentCamera->stopRecording();
+        }
+        break;
+
     case EXIT_CMD:
         {
             currentCamera->stopPreview();
diff --git a/QCamera2/HAL/test/qcamera_test.h b/QCamera2/HAL/test/qcamera_test.h
index 5bb8f67..3adf76c 100644
--- a/QCamera2/HAL/test/qcamera_test.h
+++ b/QCamera2/HAL/test/qcamera_test.h
@@ -41,6 +41,8 @@
     STOP_PREVIEW_CMD = '2',
     CHANGE_PREVIEW_SIZE_CMD = '4',
     CHANGE_PICTURE_SIZE_CMD = '5',
+    START_RECORD_CMD = '7',
+    STOP_RECORD_CMD = '8',
     DUMP_CAPS_CMD = 'E',
     AUTOFOCUS_CMD = 'f',
     TAKEPICTURE_CMD = 'p',
@@ -56,6 +58,7 @@
         mResizePreview(true),
         mHardwareActive(false),
         mPreviewRunning(false),
+        mRecordRunning(false),
         mCamera(NULL),
         mClient(NULL),
         mSurfaceControl(NULL),
@@ -70,6 +73,8 @@
     status_t autoFocus();
     status_t enablePreviewCallbacks();
     status_t takePicture();
+    status_t startRecording();
+    status_t stopRecording();
 
     status_t nextPreviewSize();
     status_t getCurrentPreviewSize(Size &previewSize);
@@ -108,6 +113,7 @@
     bool mResizePreview;
     bool mHardwareActive;
     bool mPreviewRunning;
+    bool mRecordRunning;
 
     sp<Camera> mCamera;
     sp<SurfaceComposerClient> mClient;