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,