Camera3: Add support channel when there is only one raw stream
This makes sure that in the case of single raw stream:
1. Metadata and statistics can be collected for raw result.
2. Works around a mm-camera daemon limitation where single raw
stream cannot be supported.
Bug: 14014546
Change-Id: I7a3787b8190f7d01d3dc2c43f8ab174a855ccc16
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index aaaa5b1..de2557b 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -2480,5 +2480,96 @@
return rc;
}
+cam_dimension_t QCamera3SupportChannel::kDim = {640, 480};
+
+QCamera3SupportChannel::QCamera3SupportChannel(uint32_t cam_handle,
+ mm_camera_ops_t *cam_ops,
+ cam_padding_info_t *paddingInfo,
+ void *userData) :
+ QCamera3Channel(cam_handle, cam_ops,
+ NULL, paddingInfo, userData),
+ mMemory(NULL)
+{
+}
+
+QCamera3SupportChannel::~QCamera3SupportChannel()
+{
+ if (m_bIsActive)
+ stop();
+
+ if (mMemory) {
+ mMemory->deallocate();
+ delete mMemory;
+ mMemory = NULL;
+ }
+}
+
+int32_t QCamera3SupportChannel::initialize()
+{
+ int32_t rc;
+
+ if (mMemory || m_numStreams > 0) {
+ ALOGE("%s: metadata channel already initialized", __func__);
+ return -EINVAL;
+ }
+
+ rc = init(NULL, NULL);
+ if (rc < 0) {
+ ALOGE("%s: init failed", __func__);
+ return rc;
+ }
+
+ // Hardcode to VGA size for now
+ rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_CALLBACK,
+ CAM_FORMAT_YUV_420_NV21, kDim, MIN_STREAMING_BUFFER_NUM);
+ if (rc < 0) {
+ ALOGE("%s: addStream failed", __func__);
+ }
+ return rc;
+}
+
+int32_t QCamera3SupportChannel::request(buffer_handle_t * /*buffer*/,
+ uint32_t /*frameNumber*/)
+{
+ return NO_ERROR;
+}
+
+void QCamera3SupportChannel::streamCbRoutine(
+ mm_camera_super_buf_t *super_frame,
+ QCamera3Stream * /*stream*/)
+{
+ if (super_frame == NULL || super_frame->num_bufs != 1) {
+ ALOGE("%s: super_frame is not valid", __func__);
+ return;
+ }
+ bufDone(super_frame);
+ free(super_frame);
+}
+
+QCamera3Memory* QCamera3SupportChannel::getStreamBufs(uint32_t len)
+{
+ int rc;
+
+ mMemory = new QCamera3HeapMemory();
+ if (!mMemory) {
+ ALOGE("%s: unable to create heap memory", __func__);
+ return NULL;
+ }
+ rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true);
+ if (rc < 0) {
+ ALOGE("%s: unable to allocate heap memory", __func__);
+ delete mMemory;
+ mMemory = NULL;
+ return NULL;
+ }
+ return mMemory;
+}
+
+void QCamera3SupportChannel::putStreamBufs()
+{
+ mMemory->deallocate();
+ delete mMemory;
+ mMemory = NULL;
+}
}; // namespace qcamera
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.h b/camera/QCamera2/HAL3/QCamera3Channel.h
index a7da610..2758261 100755
--- a/camera/QCamera2/HAL3/QCamera3Channel.h
+++ b/camera/QCamera2/HAL3/QCamera3Channel.h
@@ -137,7 +137,7 @@
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
- virtual QCamera3Memory *getStreamBufs(uint32_t le);
+ virtual QCamera3Memory *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
mm_camera_buf_def_t* getInternalFormatBuffer(buffer_handle_t* buffer);
virtual int32_t registerBuffer(buffer_handle_t *buffer);
@@ -171,7 +171,7 @@
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
- virtual QCamera3Memory *getStreamBufs(uint32_t le);
+ virtual QCamera3Memory *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
{ return NO_ERROR; };
@@ -200,7 +200,7 @@
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
- virtual QCamera3Memory *getStreamBufs(uint32_t le);
+ virtual QCamera3Memory *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
void dumpRawSnapshot(mm_camera_buf_def_t *frame);
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
@@ -263,7 +263,7 @@
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
- virtual QCamera3Memory *getStreamBufs(uint32_t le);
+ virtual QCamera3Memory *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
bool isWNREnabled() {return m_bWNROn;};
@@ -346,6 +346,32 @@
QCamera3HeapMemory *mMemory;
};
+/* QCamera3SupportChannel is for HAL internal consumption only */
+class QCamera3SupportChannel : public QCamera3Channel
+{
+public:
+ QCamera3SupportChannel(uint32_t cam_handle,
+ mm_camera_ops_t *cam_ops,
+ cam_padding_info_t *paddingInfo,
+ void *userData);
+ virtual ~QCamera3SupportChannel();
+
+ virtual int32_t initialize();
+
+ virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
+ virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
+ QCamera3Stream *stream);
+
+ virtual QCamera3Memory *getStreamBufs(uint32_t le);
+ virtual void putStreamBufs();
+ virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
+ { return NO_ERROR; };
+
+ static cam_dimension_t kDim;
+private:
+ QCamera3HeapMemory *mMemory;
+};
+
}; // namespace qcamera
#endif /* __QCAMERA_CHANNEL_H__ */
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index efc8176..d7229ff 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -239,6 +239,7 @@
mMetadataChannel(NULL),
mPictureChannel(NULL),
mRawChannel(NULL),
+ mSupportChannel(NULL),
mFirstRequest(false),
mParamHeap(NULL),
mParameters(NULL),
@@ -298,6 +299,8 @@
channel->stop();
}
}
+ if (mSupportChannel)
+ mSupportChannel->stop();
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
it != mStreamInfo.end(); it++) {
@@ -306,6 +309,10 @@
delete channel;
free (*it);
}
+ if (mSupportChannel) {
+ delete mSupportChannel;
+ mSupportChannel = NULL;
+ }
mPictureChannel = NULL;
@@ -616,6 +623,33 @@
return rc;
}
+ /* Create dummy stream if there is one single raw stream */
+ if (streamList->num_streams == 1 &&
+ (streamList->streams[0]->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
+ streamList->streams[0]->format == HAL_PIXEL_FORMAT_RAW16)) {
+ mSupportChannel = new QCamera3SupportChannel(
+ mCameraHandle->camera_handle,
+ mCameraHandle->ops,
+ &gCamCapability[mCameraId]->padding_info,
+ this);
+ if (!mSupportChannel) {
+ ALOGE("%s: dummy channel cannot be created", __func__);
+ pthread_mutex_unlock(&mMutex);
+ return -ENOMEM;
+ }
+
+ rc = mSupportChannel->initialize();
+ if (rc < 0) {
+ ALOGE("%s: dummy channel initialization failed", __func__);
+ delete mSupportChannel;
+ mSupportChannel = NULL;
+ delete mMetadataChannel;
+ mMetadataChannel = NULL;
+ pthread_mutex_unlock(&mMutex);
+ return rc;
+ }
+ }
+
/* Allocate channel objects for the requested streams */
for (size_t i = 0; i < streamList->num_streams; i++) {
camera3_stream_t *newStream = streamList->streams[i];
@@ -769,6 +803,13 @@
int32_t hal_version = CAM_HAL_V3;
stream_config_info.num_streams = streamList->num_streams;
+ if (mSupportChannel) {
+ stream_config_info.stream_sizes[stream_config_info.num_streams] =
+ QCamera3SupportChannel::kDim;
+ stream_config_info.type[stream_config_info.num_streams] =
+ CAM_STREAM_TYPE_CALLBACK;
+ stream_config_info.num_streams++;
+ }
// settings/parameters don't carry over for new configureStreams
memset(mParameters, 0, sizeof(metadata_buffer_t));
@@ -1059,7 +1100,7 @@
mCallbackOps->notify(mCallbackOps, ¬ify_msg);
i->timestamp = notify_msg.message.shutter.timestamp;
i->bNotified = 1;
- ALOGV("%s: Dummy notification !!!! notify frame_number = %d, capture_time = %lld",
+ ALOGV("%s: Support notification !!!! notify frame_number = %d, capture_time = %lld",
__func__, i->frame_number, notify_msg.message.shutter.timestamp);
}
@@ -1479,6 +1520,9 @@
ALOGD("%s: Start META Channel", __func__);
mMetadataChannel->start();
+ if (mSupportChannel)
+ mSupportChannel->start();
+
//First initialize all streams
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
it != mStreamInfo.end(); it++) {
@@ -1486,6 +1530,8 @@
rc = channel->initialize();
if (NO_ERROR != rc) {
ALOGE("%s : Channel initialization failed %d", __func__, rc);
+ if (mSupportChannel)
+ mSupportChannel->stop();
mMetadataChannel->stop();
pthread_mutex_unlock(&mMutex);
return rc;
@@ -1731,6 +1777,9 @@
(*it)->status = INVALID;
}
+ if (mSupportChannel) {
+ mSupportChannel->stop();
+ }
if (mMetadataChannel) {
/* If content of mStreamInfo is not 0, there is metadata stream */
mMetadataChannel->stop();
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 299e07b..aa4a30a 100755
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -227,6 +227,7 @@
QCamera3MetadataChannel *mMetadataChannel;
QCamera3PicChannel *mPictureChannel;
QCamera3RawChannel *mRawChannel;
+ QCamera3SupportChannel *mSupportChannel;
//First request yet to be processed after configureStreams
bool mFirstRequest;