Camera3: Implement process_capture_request and metadata channel

Also add getStreamBufs and putStreamBufs functions in channel
class to be used by getBufs/putBufs from stream.

Change-Id: I8e3ef37cfdb046ffe75ba1a5c1a8c0f7ac072763
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index 770f097..526d14d 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -37,6 +37,8 @@
 
 using namespace android;
 
+#define MIN_STREAMING_BUFFER_NUM 3
+
 namespace qcamera {
 
 /*===========================================================================
@@ -138,6 +140,7 @@
         return UNKNOWN_ERROR;
     }
     mPaddingInfo = paddingInfo;
+    mUserData = userData;
     return NO_ERROR;
 }
 
@@ -162,8 +165,7 @@
                                   cam_format_t streamFormat,
                                   cam_dimension_t streamDim,
                                   uint8_t minStreamBufNum,
-                                  cam_padding_info_t *paddingInfo,
-                                  QCamera3Memory *memory)
+                                  cam_padding_info_t *paddingInfo)
 {
     int32_t rc = NO_ERROR;
     if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
@@ -175,7 +177,7 @@
                                                m_handle,
                                                m_camOps,
                                                paddingInfo,
-                                               memory);
+                                               this);
     if (pStream == NULL) {
         ALOGE("%s: No mem for Stream", __func__);
         return NO_MEMORY;
@@ -364,6 +366,7 @@
                     camera3_stream_t *stream) :
                         QCamera3Channel(cam_handle, cam_ops, cb_routine),
                         mCamera3Stream(stream),
+                        mNumBufs(0),
                         mCamera3Buffers(NULL),
                         mMemory(NULL)
 {
@@ -382,9 +385,6 @@
 QCamera3RegularChannel::~QCamera3RegularChannel()
 {
     //TODO
-    if (mMemory) {
-        delete mMemory;
-    }
 }
 
 /*===========================================================================
@@ -399,7 +399,7 @@
  *              -EINVAL on invalid input
  *              -ENODEV on serious error
  *==========================================================================*/
-int32_t QCamera3RegularChannel::request(camera3_stream_buffer_t *buffer)
+int32_t QCamera3RegularChannel::request(const camera3_stream_buffer_t *buffer)
 {
     //TODO
     return 0;
@@ -445,71 +445,142 @@
         return -EINVAL;
     }
 
-    mMemory = new QCamera3GrallocMemory();
-    if (mMemory == NULL) {
-        return -ENOMEM;
-    }
-
-    rc = mMemory->registerBuffers(num_buffers, buffers);
-    if (rc < 0) {
-        delete mMemory;
-        return rc;
-    }
+    mNumBufs = num_buffers;
+    mCamera3Buffers = buffers;
 
     streamDim.width = mCamera3Stream->width;
     streamDim.height = mCamera3Stream->height;
     rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
-        num_buffers, mPaddingInfo, mMemory);
+        num_buffers, mPaddingInfo);
 
     return rc;
 }
 
-void QCamera3RegularChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
+void QCamera3RegularChannel::streamCbRoutine(
+                            mm_camera_super_buf_t *super_frame,
                             QCamera3Stream *stream)
 {
     //TODO
     return;
 }
 
+QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/)
+{
+    int rc;
+    mMemory = new QCamera3GrallocMemory();
+    if (mMemory == NULL) {
+        return NULL;
+    }
+
+    rc = mMemory->registerBuffers(mNumBufs, mCamera3Buffers);
+    if (rc < 0) {
+        delete mMemory;
+        mMemory = NULL;
+        return NULL;
+    }
+    return mMemory;
+}
+
+void QCamera3RegularChannel::putStreamBufs()
+{
+    mMemory->unregisterBuffers();
+    delete mMemory;
+    mMemory = NULL;
+}
+
 int QCamera3RegularChannel::kMaxBuffers = 3;
 
 QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
                     mm_camera_ops_t *cam_ops,
                     channel_cb_routine cb_routine) :
-                        QCamera3Channel(cam_handle, cam_ops, cb_routine)
+                        QCamera3Channel(cam_handle, cam_ops, cb_routine),
+                        mMemory(NULL),
+                        mStarted(false)
 {
-    //TODO
 }
 
 QCamera3MetadataChannel::~QCamera3MetadataChannel()
 {
-    //TODO
+    if (mStarted)
+        stop();
+
+    if (mMemory) {
+        mMemory->deallocate();
+        delete mMemory;
+        mMemory = NULL;
+    }
 }
 
 int32_t QCamera3MetadataChannel::initialize()
 {
-    //TODO
-    return 0;
+    int32_t rc;
+    cam_dimension_t streamDim;
+
+    if (mMemory || m_numStreams > 0) {
+        ALOGE("%s: metadata channel already initialized", __func__);
+        return -EINVAL;
+    }
+
+    streamDim.width = sizeof(parm_buffer_t),
+    streamDim.height = 1;
+    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
+        streamDim, MIN_STREAMING_BUFFER_NUM, mPaddingInfo);
+    if (rc < 0) {
+        ALOGE("%s: addStream failed", __func__);
+    }
+    return rc;
 }
 
-int32_t QCamera3MetadataChannel::request(camera3_stream_buffer_t *buffer)
+int32_t QCamera3MetadataChannel::request(const camera3_stream_buffer_t *buffer)
 {
-    //TODO: If not already started, start streaming
-    start();
-    return 0;
+    if (!mStarted)
+        return start();
+    else
+        return 0;
 }
 
-int32_t QCamera3MetadataChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
+int32_t QCamera3MetadataChannel::registerBuffers(uint32_t num_buffers,
+                                            buffer_handle_t **buffers)
 {
-    //TODO
+    // no registerBuffers are supported for metadata channel
     return -EINVAL;
 }
 
-void QCamera3MetadataChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
-                            QCamera3Stream *stream)
+void QCamera3MetadataChannel::streamCbRoutine(
+                        mm_camera_super_buf_t *super_frame,
+                        QCamera3Stream *stream)
 {
-    //TODO
-    return;
+    if (super_frame == NULL || super_frame->num_bufs != 1) {
+        ALOGE("%s: super_frame is not valid", __func__);
+        return;
+    }
+    mChannelCB(super_frame->bufs[0], NULL, mUserData);
+}
+
+QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t /*len*/)
+{
+    int rc;
+    mMemory = new QCamera3HeapMemory();
+    if (!mMemory) {
+        ALOGE("%s: unable to create metadata memory", __func__);
+        return NULL;
+    }
+    rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, sizeof(parm_buffer_t), true);
+    if (rc < 0) {
+        ALOGE("%s: unable to allocate metadata memory", __func__);
+        delete mMemory;
+        mMemory = NULL;
+        return NULL;
+    }
+    memset(mMemory->getPtr(0), 0, sizeof(parm_buffer_t));
+    return mMemory;
+}
+
+void QCamera3MetadataChannel::putStreamBufs()
+{
+    mMemory->deallocate();
+    delete mMemory;
+    mMemory = NULL;
 }
 
 QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
@@ -525,7 +596,7 @@
 {
 }
 
-int32_t QCamera3PicChannel::request(camera3_stream_buffer_t *buffer)
+int32_t QCamera3PicChannel::request(const camera3_stream_buffer_t *buffer)
 {
     //TODO
     return 0;
@@ -545,5 +616,31 @@
     return;
 }
 
+QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
+{
+    int rc = 0;
+    mYuvMemory = new QCamera3HeapMemory();
+    if (!mYuvMemory) {
+        ALOGE("%s: unable to create metadata memory", __func__);
+        return NULL;
+    }
+
+    rc = mYuvMemory->allocate(1, len, false);
+    if (rc < 0) {
+        ALOGE("%s: unable to allocate metadata memory", __func__);
+        delete mYuvMemory;
+        mYuvMemory = NULL;
+        return NULL;
+    }
+    return mYuvMemory;
+}
+
+void QCamera3PicChannel::putStreamBufs()
+{
+    mYuvMemory->deallocate();
+    delete mYuvMemory;
+    mYuvMemory = NULL;
+}
+
 int QCamera3PicChannel::kMaxBuffers = 1;
 }; // namespace qcamera
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.h b/camera/QCamera2/HAL3/QCamera3Channel.h
index 86e2942..9b53d56 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.h
+++ b/camera/QCamera2/HAL3/QCamera3Channel.h
@@ -53,21 +53,25 @@
                    channel_cb_routine cb_routine);
     QCamera3Channel();
     virtual ~QCamera3Channel();
-    virtual int32_t addStream(cam_stream_type_t streamType,
+
+    int32_t addStream(cam_stream_type_t streamType,
                               cam_format_t streamFormat,
                               cam_dimension_t streamDim,
                               uint8_t minStreamBufnum,
-                              cam_padding_info_t *paddingInfo,
-                              QCamera3Memory *memory);
-    virtual int32_t start();
-    virtual int32_t stop();
-    virtual int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
+                              cam_padding_info_t *paddingInfo);
+    int32_t start();
+    int32_t stop();
+    int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
+
     virtual int32_t registerBuffers(uint32_t num_buffers,
                         buffer_handle_t **buffers) = 0;
-    virtual int32_t request(camera3_stream_buffer_t *buffer) = 0;
+    virtual int32_t request(const camera3_stream_buffer_t *buffer) = 0;
     virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
                             QCamera3Stream *stream) = 0;
 
+    virtual QCamera3Memory *getStreamBufs(uint32_t len) = 0;
+    virtual void putStreamBufs() = 0;
+
     QCamera3Stream *getStreamByHandle(uint32_t streamHandle);
     uint32_t getMyHandle() const {return m_handle;};
     uint8_t getNumOfStreams() const {return m_numStreams;};
@@ -110,16 +114,21 @@
                     camera3_stream_t *stream);
     virtual ~QCamera3RegularChannel();
 
-    virtual int32_t request(camera3_stream_buffer_t *buffer);
-    virtual int32_t registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers);
-    void streamCbRoutine(mm_camera_super_buf_t *super_frame, QCamera3Stream *stream);
+    virtual int32_t request(const camera3_stream_buffer_t *buffer);
+    virtual int32_t registerBuffers(uint32_t num_buffers,
+                                buffer_handle_t **buffers);
+    virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
+                                            QCamera3Stream *stream);
+
+    virtual QCamera3Memory *getStreamBufs(uint32_t le);
+    virtual void putStreamBufs();
 
 public:
     static int kMaxBuffers;
 private:
     camera3_stream_t *mCamera3Stream;
     uint32_t mNumBufs;
-    camera3_stream_buffer_set_t *mCamera3Buffers;
+    buffer_handle_t **mCamera3Buffers;
 
     QCamera3GrallocMemory *mMemory;
 };
@@ -135,14 +144,18 @@
 
     int32_t initialize();
 
-    virtual int32_t request(camera3_stream_buffer_t *buffer);
+    virtual int32_t request(const camera3_stream_buffer_t *buffer);
     virtual int32_t registerBuffers(uint32_t num_buffers,
                 buffer_handle_t **buffers);
     virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
                             QCamera3Stream *stream);
 
+    virtual QCamera3Memory *getStreamBufs(uint32_t le);
+    virtual void putStreamBufs();
+
 private:
     QCamera3HeapMemory *mMemory;
+    bool mStarted;
 };
 
 /* QCamera3PicChannel is for JPEG stream, which contains a YUV stream generated
@@ -156,11 +169,15 @@
                     camera3_stream_t *stream);
     ~QCamera3PicChannel();
 
-    virtual int32_t request(camera3_stream_buffer_t *buffer);
+    virtual int32_t request(const camera3_stream_buffer_t *buffer);
     virtual int32_t registerBuffers(uint32_t num_buffers,
                         buffer_handle_t **buffers);
     virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
                             QCamera3Stream *stream);
+
+    virtual QCamera3Memory *getStreamBufs(uint32_t le);
+    virtual void putStreamBufs();
+
 public:
     static int kMaxBuffers;
 private:
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index b5c701b..006c139 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -83,6 +83,10 @@
     mCameraDevice.ops = &mCameraOps;
     mCameraDevice.priv = this;
     gCamCapability[cameraId]->version = CAM_HAL_V3;
+
+    pthread_mutex_init(&mRequestLock, NULL);
+    pthread_cond_init(&mRequestCond, NULL);
+    mPendingRequest = 0;
 }
 
 /*===========================================================================
@@ -227,16 +231,55 @@
 int QCamera3HardwareInterface::initialize(
         const struct camera3_callback_ops *callback_ops)
 {
-    mCallbackOps = callback_ops;
+    int rc;
 
-    //TODO:Create metadata channel and initialize it
+    //Create metadata channel and initialize it
     mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
-                                        mCameraHandle->ops, channelCbRoutine);
+                                        mCameraHandle->ops, channelCb);
     if (mMetadataChannel == NULL) {
         ALOGE("%s: failed to allocate metadata channel", __func__);
-        return -ENOMEM;
+        rc = -ENOMEM;
+        goto err1;
     }
-    return mMetadataChannel->initialize();
+    rc = mMetadataChannel->initialize();
+    if (rc < 0) {
+        ALOGE("%s: metadata channel initialization failed", __func__);
+        goto err2;
+    }
+
+    /* Initialize parameter heap and structure */
+    mParamHeap = new QCamera3HeapMemory();
+    if (mParamHeap == NULL) {
+        ALOGE("%s: creation of mParamHeap failed", __func__);
+        goto err2;
+    }
+    rc = mParamHeap->allocate(sizeof(parm_buffer_t), 1, false);
+    if (rc < 0) {
+        ALOGE("%s: allocation of mParamHeap failed", __func__);
+        goto err3;
+    }
+    rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
+                CAM_MAPPING_BUF_TYPE_PARM_BUF,
+                mParamHeap->getFd(0), sizeof(parm_buffer_t));
+    if (rc < 0) {
+        ALOGE("%s: map_buf failed for mParamHeap", __func__);
+        goto err4;
+    }
+    mParameters = (parm_buffer_t *)DATA_PTR(mParamHeap, 0);
+
+    mCallbackOps = callback_ops;
+    return 0;
+
+err4:
+    mParamHeap->deallocate();
+err3:
+    delete mParamHeap;
+    mParamHeap = NULL;
+err2:
+    delete mMetadataChannel;
+    mMetadataChannel = NULL;
+err1:
+    return rc;
 }
 
 /*===========================================================================
@@ -287,7 +330,7 @@
     /* TODO: Clean up no longer used streams, and maintain others if this
      * is not the 1st time configureStreams is called */
 
-    /* TODO: Reconstruct/reset metadata stream/channel */
+    mMetadataChannel->stop();
 
     /* Allocate channel objects for the requested streams */
     for (size_t i = 0; i < streamList->num_streams; i++) {
@@ -320,7 +363,7 @@
                 switch (newStream->format) {
                 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
                     channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
-                            mCameraHandle->ops, channelCbRoutine, newStream);
+                            mCameraHandle->ops, channelCb, newStream);
                     if (channel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
                         return -ENOMEM;
@@ -330,7 +373,7 @@
                     break;
                 case HAL_PIXEL_FORMAT_BLOB:
                     channel = new QCamera3PicChannel(mCameraHandle->camera_handle,
-                            mCameraHandle->ops, channelCbRoutine, newStream);
+                            mCameraHandle->ops, channelCb, newStream);
                     if (channel == NULL) {
                         ALOGE("%s: allocation of channel failed", __func__);
                         return -ENOMEM;
@@ -350,6 +393,9 @@
             // Do nothing for now
         }
     }
+
+    // Cannot reuse settings across configure call
+    memset(mParameters, 0, sizeof(parm_buffer_t));
     return 0;
 }
 
@@ -405,8 +451,7 @@
 /*===========================================================================
  * FUNCTION   : processCaptureRequest
  *
- * DESCRIPTION:
- *
+ * DESCRIPTION: process a capture request from camera service
  *
  * PARAMETERS :
  *   @request : request from framework to process
@@ -414,16 +459,127 @@
  * RETURN     :
  *
  *==========================================================================*/
-int QCamera3HardwareInterface::processCaptureRequest
-                                (camera3_capture_request_t *request)
+int QCamera3HardwareInterface::processCaptureRequest(
+                    camera3_capture_request_t *request)
 {
-    /*For each frame, we have to set the requested settings*/
     int rc = NO_ERROR;
+    ssize_t idx = 0;
+    const camera3_stream_buffer_t *b;
+    CameraMetadata meta;
+
+    /* Sanity check the request */
+    if (request == NULL) {
+        ALOGE("%s: NULL capture request", __func__);
+        return BAD_VALUE;
+    }
+
+    uint32_t frameNumber = request->frame_number;
+    if (request->input_buffer != NULL &&
+            request->input_buffer->stream != mInputStream) {
+        ALOGE("%s: Request %d: Input buffer not from input stream!",
+                __FUNCTION__, frameNumber);
+        return BAD_VALUE;
+    }
+    if (request->num_output_buffers < 1 || request->output_buffers == NULL) {
+        ALOGE("%s: Request %d: No output buffers provided!",
+                __FUNCTION__, frameNumber);
+        return BAD_VALUE;
+    }
+    if (request->input_buffer != NULL) {
+        //TODO
+        ALOGE("%s: Not supporting input buffer yet", __func__);
+        return BAD_VALUE;
+    }
+
+    // Validate all buffers
+    b = request->output_buffers;
+    do {
+        QCamera3Channel *channel =
+                static_cast<QCamera3Channel*>(b->stream->priv);
+        if (channel == NULL) {
+            ALOGE("%s: Request %d: Buffer %d: Unconfigured stream!",
+                    __func__, frameNumber, idx);
+            return BAD_VALUE;
+        }
+        if (b->status != CAMERA3_BUFFER_STATUS_OK) {
+            ALOGE("%s: Request %d: Buffer %d: Status not OK!",
+                    __func__, frameNumber, idx);
+            return BAD_VALUE;
+        }
+        if (b->release_fence != -1) {
+            ALOGE("%s: Request %d: Buffer %d: Has a release fence!",
+                    __func__, frameNumber, idx);
+            return BAD_VALUE;
+        }
+        if (b->buffer == NULL) {
+            ALOGE("%s: Request %d: Buffer %d: NULL buffer handle!",
+                    __func__, frameNumber, idx);
+            return BAD_VALUE;
+        }
+        idx++;
+        b = request->output_buffers + idx;
+    } while (idx < (ssize_t)request->num_output_buffers);
+
     rc = setFrameParameters(request->settings);
-    /*do the actual processing*/
+    if (rc < 0) {
+        ALOGE("%s: fail to set frame parameters", __func__);
+        return rc;
+    }
+
+    // Notify metadata channel we receive a request
+    mMetadataChannel->request(NULL);
+
+    // Call request on other streams
+    for (size_t i = 0; i < request->num_output_buffers; i++) {
+        const camera3_stream_buffer_t& output = request->output_buffers[i];
+        QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
+        if (channel == NULL) {
+            ALOGE("%s: invalid channel pointer for stream", __func__);
+            continue;
+        }
+
+        rc = channel->request(&output);
+        if (rc < 0)
+            ALOGE("%s: request failed", __func__);
+    }
+
+    //Block on conditional variable
+    pthread_mutex_lock(&mRequestLock);
+    mPendingRequest = 1;
+    while (mPendingRequest == 1) {
+        pthread_cond_wait(&mRequestCond, &mRequestLock);
+    }
+    pthread_mutex_unlock(&mRequestLock);
+
     return rc;
 }
 
+/*===========================================================================
+ * FUNCTION   : channelCb
+ *
+ * DESCRIPTION: Callback handler for all channels (streams, as well as metadata)
+ *
+ * PARAMETERS :
+ *   @frame  : frame information from mm-camera-interface
+ *   @buffer : actual gralloc buffer to be returned to frameworks. NULL if metadata.
+ *
+ * RETURN     : NONE
+ *==========================================================================*/
+void QCamera3HardwareInterface::channelCb(mm_camera_buf_def_t *frame,
+                camera3_stream_buffer_t *buffer)
+{
+    if (frame->stream_type == CAM_STREAM_TYPE_METADATA) {
+        // Signal to unblock processCaptureRequest
+        pthread_mutex_lock(&mRequestLock);
+        mPendingRequest = 0;
+        pthread_cond_signal(&mRequestCond);
+        pthread_mutex_unlock(&mRequestLock);
+    }
+
+    //TODO: Gives frame and buffer to buffer aggregator.
+    return;
+}
+
 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
 /*===========================================================================
  * FUNCTION   : initCapabilities
@@ -451,7 +607,6 @@
     }
 
     /* Allocate memory for capability buffer */
-    capabilityHeap = new QCamera3HeapMemory();
     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), false);
     if(rc != OK) {
         ALOGE("%s: No memory for cappability", __func__);
@@ -738,7 +893,8 @@
     }
     settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
 
-    settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &gCamCapability[mCameraId]->exposure_compensation_default, 1);
+    settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+            &gCamCapability[mCameraId]->exposure_compensation_default, 1);
 
     static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
     settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
@@ -832,7 +988,7 @@
 }
 
 /*===========================================================================
- * FUNCTION   : channelCbRoutine
+ * FUNCTION   : channelCb
  *
  * DESCRIPTION: Callback handler for all channels (streams, as well as metadata)
  *
@@ -843,7 +999,7 @@
  *
  * RETURN     : NONE
  *==========================================================================*/
-void QCamera3HardwareInterface::channelCbRoutine(mm_camera_buf_def_t *frame,
+void QCamera3HardwareInterface::channelCb(mm_camera_buf_def_t *frame,
                 camera3_stream_buffer_t *buffer, void *userdata)
 {
     QCamera3HardwareInterface *hw = (QCamera3HardwareInterface *)userdata;
@@ -852,8 +1008,7 @@
         return;
     }
 
-    //TODO: Gives frame and buffer to buffer aggregator.
-
+    hw->channelCb(frame, buffer);
     return;
 }
 
@@ -941,8 +1096,9 @@
  * RETURN     : Success: Return valid metadata
  *              Failure: Return NULL
  *==========================================================================*/
-const camera_metadata_t* QCamera3HardwareInterface::construct_default_request_settings
-(const struct camera3_device *device, int type)
+const camera_metadata_t* QCamera3HardwareInterface::
+    construct_default_request_settings(const struct camera3_device *device,
+                                        int type)
 {
 
     camera_metadata_t* fwk_metadata = NULL;
@@ -968,19 +1124,18 @@
  *
  * RETURN     :
  *==========================================================================*/
-int QCamera3HardwareInterface::process_capture_request(const struct camera3_device *device,
-                                                       camera3_capture_request_t *request)
+int QCamera3HardwareInterface::process_capture_request(
+                    const struct camera3_device *device,
+                    camera3_capture_request_t *request)
 {
-    /*TODO - Implement*/
     QCamera3HardwareInterface *hw =
         reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
-    int rc = NO_ERROR;
     if (!hw) {
         ALOGE("%s: NULL camera device", __func__);
-        return -ENODEV;
+        return -EINVAL;
     }
-    rc = hw->processCaptureRequest(request);
-    return rc;
+
+    return hw->processCaptureRequest(request);
 }
 
 /*===========================================================================
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index f77abdd..3cfa694 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -30,6 +30,7 @@
 #ifndef __QCAMERA2HARDWAREINTERFACE_H__
 #define __QCAMERA2HARDWAREINTERFACE_H__
 
+#include <pthread.h>
 #include <utils/List.h>
 #include <hardware/camera3.h>
 #include <camera/CameraMetadata.h>
@@ -52,17 +53,24 @@
 #endif
 
 class QCamera3MetadataChannel;
+class QCamera3HeapMemory;
 
 class QCamera3HardwareInterface {
 public:
     /* static variable and functions accessed by camera service */
     static camera3_device_ops_t mCameraOps;
-    static int initialize(const struct camera3_device *, const camera3_callback_ops_t *callback_ops);
-    static int configure_streams(const struct camera3_device *, camera3_stream_configuration_t *stream_list);
-    static int register_stream_buffers(const struct camera3_device *, const camera3_stream_buffer_set_t *buffer_set);
-    static const camera_metadata_t* construct_default_request_settings(const struct camera3_device *, int type);
-    static int process_capture_request(const struct camera3_device *, camera3_capture_request_t *request);
-    static void get_metadata_vendor_tag_ops(const struct camera3_device *, vendor_tag_query_ops_t* ops);
+    static int initialize(const struct camera3_device *,
+                const camera3_callback_ops_t *callback_ops);
+    static int configure_streams(const struct camera3_device *,
+                camera3_stream_configuration_t *stream_list);
+    static int register_stream_buffers(const struct camera3_device *,
+                const camera3_stream_buffer_set_t *buffer_set);
+    static const camera_metadata_t* construct_default_request_settings(
+                                const struct camera3_device *, int type);
+    static int process_capture_request(const struct camera3_device *,
+                                camera3_capture_request_t *request);
+    static void get_metadata_vendor_tag_ops(const struct camera3_device *,
+                                               vendor_tag_query_ops_t* ops);
     static void dump(const struct camera3_device *, int fd);
 
 public:
@@ -71,16 +79,19 @@
     int openCamera(struct hw_device_t **hw_device);
     int getMetadata(int type);
     camera_metadata_t* translateMetadata(int type);
+    int metadataToParam(CameraMetadata &metadata);
 
     static int getCamInfo(int cameraId, struct camera_info *info);
     static int initCapabilities(int cameraId);
     static int initStaticMetadata(int cameraId);
 
-    static void channelCbRoutine(mm_camera_buf_def_t *frame,
+    static void channelCb(mm_camera_buf_def_t *frame,
                 camera3_stream_buffer_t *buffer, void *userdata);
 
-    void sendCaptureResult(const struct camera3_callback_ops *, const camera3_capture_result_t *result);
-    void notify(const struct camera3_callback_ops *, const camera3_notify_msg_t *msg);
+    void sendCaptureResult(const struct camera3_callback_ops *,
+                        const camera3_capture_result_t *result);
+    void notify(const struct camera3_callback_ops *,
+                        const camera3_notify_msg_t *msg);
 
     int initialize(const camera3_callback_ops_t *callback_ops);
     int configureStreams(camera3_stream_configuration_t *stream_list);
@@ -89,6 +100,10 @@
 
     int setFrameParameters(const camera_metadata_t *settings);
     int translateMetadataToParameters(const camera_metadata_t *settings);
+
+    void channelCb(mm_camera_buf_def_t *frame,
+                camera3_stream_buffer_t *buffer);
+
 private:
 
     int openCamera();
@@ -107,6 +122,14 @@
 
     camera3_stream_t *mInputStream;
     QCamera3MetadataChannel *mMetadataChannel;
+
+    QCamera3HeapMemory *mParamHeap;
+    parm_buffer_t* mParameters;
+
+    //mutex and conditional variable for request
+    pthread_mutex_t mRequestLock;
+    pthread_cond_t mRequestCond;
+    int mPendingRequest;
 };
 
 }; // namespace qcamera
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.cpp b/camera/QCamera2/HAL3/QCamera3Stream.cpp
index f932ca0..aad4580 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Stream.cpp
@@ -33,6 +33,7 @@
 #include <utils/Errors.h>
 #include "QCamera3HWI.h"
 #include "QCamera3Stream.h"
+#include "QCamera3Channel.h"
 
 using namespace android;
 
@@ -115,7 +116,7 @@
                              uint32_t chId,
                              mm_camera_ops_t *camOps,
                              cam_padding_info_t *paddingInfo,
-                             QCamera3Memory *memory) :
+                             QCamera3Channel *channel) :
         mCamHandle(camHandle),
         mChannelHandle(chId),
         mHandle(0),
@@ -124,8 +125,9 @@
         mNumBufs(0),
         mDataCB(NULL),
         mStreamInfoBuf(NULL),
-        mStreamBufs(memory),
-        mBufDefs(NULL)
+        mStreamBufs(NULL),
+        mBufDefs(NULL),
+        mChannel(channel)
 {
     mMemVtbl.user_data = this;
     mMemVtbl.get_bufs = get_bufs;
@@ -502,6 +504,7 @@
 
     mFrameLenOffset = *offset;
 
+    mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
     if (!mStreamBufs) {
         ALOGE("%s: Failed to allocate stream buffers", __func__);
         return NO_MEMORY;
@@ -586,6 +589,7 @@
     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));
+    mChannel->putStreamBufs();
 
     return rc;
 }
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.h b/camera/QCamera2/HAL3/QCamera3Stream.h
index 7233fcf..2f44775 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.h
+++ b/camera/QCamera2/HAL3/QCamera3Stream.h
@@ -41,6 +41,8 @@
 namespace qcamera {
 
 class QCamera3Stream;
+class QCamera3Channel;
+
 typedef void (*stream_cb_routine)(mm_camera_super_buf_t *frame,
                                   QCamera3Stream *stream,
                                   void *userdata);
@@ -52,7 +54,7 @@
                   uint32_t chId,
                   mm_camera_ops_t *camOps,
                   cam_padding_info_t *paddingInfo,
-                  QCamera3Memory *memory);
+                  QCamera3Channel *channel);
     virtual ~QCamera3Stream();
     virtual int32_t init(cam_stream_type_t streamType,
                          cam_format_t streamFormat,
@@ -100,6 +102,7 @@
     mm_camera_buf_def_t *mBufDefs;
     cam_frame_len_offset_t mFrameLenOffset;
     cam_padding_info_t mPaddingInfo;
+    QCamera3Channel *mChannel;
 
     static int32_t get_bufs(
                      cam_frame_len_offset_t *offset,