summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/camera/Camera.cpp40
-rw-r--r--modules/camera/Camera.h2
-rw-r--r--modules/camera/Metadata.cpp80
-rw-r--r--modules/camera/Metadata.h4
-rw-r--r--modules/camera/Stream.cpp8
-rw-r--r--modules/camera/Stream.h2
6 files changed, 116 insertions, 20 deletions
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index 3bafdf4..137c5f6 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -135,6 +135,29 @@ int Camera::initialize(const camera3_callback_ops_t *callback_ops)
{
ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
mCallbackOps = callback_ops;
+ // Create standard settings templates
+ // 0 is invalid as template
+ mTemplates[0] = NULL;
+ // CAMERA3_TEMPLATE_PREVIEW = 1
+ mTemplates[1] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
+ // CAMERA3_TEMPLATE_STILL_CAPTURE = 2
+ mTemplates[2] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+ // CAMERA3_TEMPLATE_VIDEO_RECORD = 3
+ mTemplates[3] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ // CAMERA3_TEMPLATE_VIDEO_SNAPSHOT = 4
+ mTemplates[4] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+ // CAMERA3_TEMPLATE_STILL_ZERO_SHUTTER_LAG = 5
+ mTemplates[5] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
+ // Pre-generate metadata structures
+ for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
+ mTemplates[i]->generate();
+ }
+ // TODO: create vendor templates
return 0;
}
@@ -303,10 +326,13 @@ int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
// Fill new stream array with reused streams and new streams
for (unsigned int i = 0; i < stream_config->num_streams; i++) {
astream = stream_config->streams[i];
- if (astream->max_buffers > 0)
+ if (astream->max_buffers > 0) {
+ ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
newStreams[i] = reuseStream(astream);
- else
+ } else {
+ ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
newStreams[i] = new Stream(mId, astream);
+ }
if (newStreams[i] == NULL) {
ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
@@ -388,6 +414,8 @@ bool Camera::isValidStreamSet(Stream **streams, int count)
if (streams[i]->isOutputType())
outputs++;
}
+ ALOGV("%s:%d: Configuring %d output streams and %d input streams",
+ __func__, mId, outputs, inputs);
if (outputs < 1) {
ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
return false;
@@ -445,8 +473,12 @@ int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set)
const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
{
ALOGV("%s:%d: type=%d", __func__, mId, type);
- // TODO: return statically built default request
- return NULL;
+
+ if (type < 1 || type >= CAMERA3_TEMPLATE_COUNT) {
+ ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
+ return NULL;
+ }
+ return mTemplates[type]->generate();
}
int Camera::processCaptureRequest(camera3_capture_request_t *request)
diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h
index e97dfd0..c7ee52d 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/Camera.h
@@ -91,6 +91,8 @@ class Camera {
Stream **mStreams;
// Number of streams in mStreams
int mNumStreams;
+ // Static array of standard camera settings templates
+ Metadata *mTemplates[CAMERA3_TEMPLATE_COUNT];
// Most recent request settings seen, memoized to be reused
camera_metadata_t *mSettings;
};
diff --git a/modules/camera/Metadata.cpp b/modules/camera/Metadata.cpp
index 77f5405..362a087 100644
--- a/modules/camera/Metadata.cpp
+++ b/modules/camera/Metadata.cpp
@@ -33,7 +33,9 @@ Metadata::Metadata()
: mHead(NULL),
mTail(NULL),
mEntryCount(0),
- mDataCount(0)
+ mDataCount(0),
+ mGenerated(NULL),
+ mDirty(true)
{
// NULL (default) pthread mutex attributes
pthread_mutex_init(&mMutex, NULL);
@@ -41,6 +43,37 @@ Metadata::Metadata()
Metadata::~Metadata()
{
+ if (mGenerated != NULL)
+ free_camera_metadata(mGenerated);
+}
+
+Metadata::Metadata(uint8_t mode, uint8_t intent)
+ : mHead(NULL),
+ mTail(NULL),
+ mEntryCount(0),
+ mDataCount(0),
+ mGenerated(NULL),
+ mDirty(true)
+{
+ pthread_mutex_init(&mMutex, NULL);
+
+ if (validate(ANDROID_CONTROL_MODE, TYPE_BYTE, 1)) {
+ int res = add(ANDROID_CONTROL_MODE, 1, &mode);
+ if (res != 0) {
+ ALOGE("%s: Unable to add mode to template!", __func__);
+ }
+ } else {
+ ALOGE("%s: Invalid mode constructing template!", __func__);
+ }
+
+ if (validate(ANDROID_CONTROL_CAPTURE_INTENT, TYPE_BYTE, 1)) {
+ int res = add(ANDROID_CONTROL_CAPTURE_INTENT, 1, &intent);
+ if (res != 0) {
+ ALOGE("%s: Unable to add capture intent to template!", __func__);
+ }
+ } else {
+ ALOGE("%s: Invalid capture intent constructing template!", __func__);
+ }
}
int Metadata::addUInt8(uint32_t tag, int count, uint8_t *data)
@@ -113,33 +146,54 @@ int Metadata::add(uint32_t tag, int count, void *tag_data)
return -ENOMEM;
memcpy(data, tag_data, count * type_sz);
+ pthread_mutex_lock(&mMutex);
mEntryCount++;
mDataCount += calculate_camera_metadata_entry_data_size(tag_type, count);
push(new Entry(tag, data, count));
+ mDirty = true;
+ pthread_mutex_unlock(&mMutex);
return 0;
}
camera_metadata_t* Metadata::generate()
{
- Entry *current = mHead;
+ Entry *current;
pthread_mutex_lock(&mMutex);
+ // Reuse if old generated metadata still valid
+ if (!mDirty && mGenerated != NULL) {
+ ALOGV("%s: Reusing generated metadata at %p", __func__, mGenerated);
+ goto out;
+ }
+ // Destroy old metadata
+ if (mGenerated != NULL) {
+ ALOGV("%s: Freeing generated metadata at %p", __func__, mGenerated);
+ free_camera_metadata(mGenerated);
+ mGenerated = NULL;
+ }
+ // Generate new metadata structure
+ ALOGV("%s: Generating new camera metadata structure, Entries:%d Data:%d",
+ __func__, mEntryCount, mDataCount);
+ mGenerated = allocate_camera_metadata(mEntryCount, mDataCount);
if (mGenerated == NULL) {
- ALOGV("Generating new camera metadata structure");
- mGenerated = allocate_camera_metadata(mEntryCount, mDataCount);
- if (mGenerated == NULL) {
- ALOGE("%s: Failed to allocate metadata (%d entries %d data)",
- __func__, mEntryCount, mDataCount);
- }
+ ALOGE("%s: Failed to allocate metadata (%d entries %d data)",
+ __func__, mEntryCount, mDataCount);
+ goto out;
}
// Walk list of entries adding each one to newly allocated metadata
- while (current != NULL) {
- add_camera_metadata_entry(mGenerated, current->mTag, current->mData,
- current->mCount);
- current = current->mNext;
+ for (current = mHead; current != NULL; current = current->mNext) {
+ int res = add_camera_metadata_entry(mGenerated, current->mTag,
+ current->mData, current->mCount);
+ if (res != 0) {
+ ALOGE("%s: Failed to add camera metadata: %d", __func__, res);
+ free_camera_metadata(mGenerated);
+ mGenerated = NULL;
+ goto out;
+ }
}
- pthread_mutex_unlock(&mMutex);
+out:
+ pthread_mutex_unlock(&mMutex);
return mGenerated;
}
diff --git a/modules/camera/Metadata.h b/modules/camera/Metadata.h
index d5aac36..22d2f22 100644
--- a/modules/camera/Metadata.h
+++ b/modules/camera/Metadata.h
@@ -28,6 +28,8 @@ class Metadata {
public:
Metadata();
~Metadata();
+ // Constructor used for request metadata templates
+ Metadata(uint8_t mode, uint8_t intent);
// Parse and add an entry
int addUInt8(uint32_t tag, int count, uint8_t *data);
@@ -67,6 +69,8 @@ class Metadata {
int mDataCount;
// Save generated metadata, invalidated on update
camera_metadata_t *mGenerated;
+ // Flag to force metadata regeneration
+ bool mDirty;
// Lock protecting the Metadata object for modifications
pthread_mutex_t mMutex;
};
diff --git a/modules/camera/Stream.cpp b/modules/camera/Stream.cpp
index 0834aee..aae7adb 100644
--- a/modules/camera/Stream.cpp
+++ b/modules/camera/Stream.cpp
@@ -61,6 +61,7 @@ void Stream::setUsage(uint32_t usage)
pthread_mutex_lock(&mMutex);
if (usage != mUsage) {
mUsage = usage;
+ mStream->usage = usage;
unregisterBuffers_L();
}
pthread_mutex_unlock(&mMutex);
@@ -71,6 +72,7 @@ void Stream::setMaxBuffers(uint32_t max_buffers)
pthread_mutex_lock(&mMutex);
if (max_buffers != mMaxBuffers) {
mMaxBuffers = max_buffers;
+ mStream->max_buffers = max_buffers;
unregisterBuffers_L();
}
pthread_mutex_unlock(&mMutex);
@@ -83,12 +85,14 @@ int Stream::getType()
bool Stream::isInputType()
{
- return mType & (CAMERA3_STREAM_INPUT | CAMERA3_STREAM_BIDIRECTIONAL);
+ return mType == CAMERA3_STREAM_INPUT ||
+ mType == CAMERA3_STREAM_BIDIRECTIONAL;
}
bool Stream::isOutputType()
{
- return mType & (CAMERA3_STREAM_OUTPUT | CAMERA3_STREAM_BIDIRECTIONAL);
+ return mType == CAMERA3_STREAM_OUTPUT ||
+ mType == CAMERA3_STREAM_BIDIRECTIONAL;
}
bool Stream::isRegistered()
diff --git a/modules/camera/Stream.h b/modules/camera/Stream.h
index 521362e..34abd95 100644
--- a/modules/camera/Stream.h
+++ b/modules/camera/Stream.h
@@ -52,7 +52,7 @@ class Stream {
// The camera device id this stream belongs to
const int mId;
// Handle to framework's stream, used as a cookie for buffers
- const camera3_stream_t *mStream;
+ camera3_stream_t *mStream;
// Stream type: CAMERA3_STREAM_* (see <hardware/camera3.h>)
const int mType;
// Width in pixels of the buffers in this stream