modules: camera: Add buffer registration scaffold

Change-Id: Ic1d20dd7f93a0ca3cd2c3af3b33a7a9df47b5e89
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index b06f65d..21ac232 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -262,8 +262,16 @@
 int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set)
 {
     ALOGV("%s:%d: buffer_set=%p", __func__, mId, buf_set);
-    // TODO: register buffers with hardware
-    return 0;
+    if (buf_set == NULL) {
+        ALOGE("%s:%d: NULL buffer set", __func__, mId);
+        return -EINVAL;
+    }
+    if (buf_set->stream == NULL) {
+        ALOGE("%s:%d: NULL stream handle", __func__, mId);
+        return -EINVAL;
+    }
+    Stream *stream = reinterpret_cast<Stream*>(buf_set->stream->priv);
+    return stream->registerBuffers(buf_set);
 }
 
 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
diff --git a/modules/camera/Stream.cpp b/modules/camera/Stream.cpp
index 08ae159..0834aee 100644
--- a/modules/camera/Stream.cpp
+++ b/modules/camera/Stream.cpp
@@ -41,7 +41,9 @@
     mFormat(s->format),
     mUsage(0),
     mMaxBuffers(0),
-    mRegistered(false)
+    mRegistered(false),
+    mBuffers(0),
+    mNumBuffers(0)
 {
     // NULL (default) pthread mutex attributes
     pthread_mutex_init(&mMutex, NULL);
@@ -49,7 +51,9 @@
 
 Stream::~Stream()
 {
-    // TODO: unregister buffers from hw
+    pthread_mutex_lock(&mMutex);
+    unregisterBuffers_L();
+    pthread_mutex_unlock(&mMutex);
 }
 
 void Stream::setUsage(uint32_t usage)
@@ -57,8 +61,7 @@
     pthread_mutex_lock(&mMutex);
     if (usage != mUsage) {
         mUsage = usage;
-        mRegistered = false;
-        // TODO: unregister buffers from hw
+        unregisterBuffers_L();
     }
     pthread_mutex_unlock(&mMutex);
 }
@@ -68,8 +71,7 @@
     pthread_mutex_lock(&mMutex);
     if (max_buffers != mMaxBuffers) {
         mMaxBuffers = max_buffers;
-        mRegistered = false;
-        // TODO: unregister buffers from hw
+        unregisterBuffers_L();
     }
     pthread_mutex_unlock(&mMutex);
 }
@@ -89,6 +91,11 @@
     return mType & (CAMERA3_STREAM_OUTPUT | CAMERA3_STREAM_BIDIRECTIONAL);
 }
 
+bool Stream::isRegistered()
+{
+    return mRegistered;
+}
+
 bool Stream::isValidReuseStream(int id, camera3_stream_t *s)
 {
     if (id != mId) {
@@ -126,4 +133,41 @@
     return true;
 }
 
+int Stream::registerBuffers(const camera3_stream_buffer_set_t *buf_set)
+{
+    CAMTRACE_CALL();
+
+    if (buf_set->stream != mStream) {
+        ALOGE("%s:%d: Buffer set for invalid stream. Got %p expect %p",
+                __func__, mId, buf_set->stream, mStream);
+        return -EINVAL;
+    }
+
+    pthread_mutex_lock(&mMutex);
+
+    mNumBuffers = buf_set->num_buffers;
+    mBuffers = new buffer_handle_t*[mNumBuffers];
+
+    for (unsigned int i = 0; i < mNumBuffers; i++) {
+        ALOGV("%s:%d: Registering buffer %p", __func__, mId,
+                buf_set->buffers[i]);
+        mBuffers[i] = buf_set->buffers[i];
+        // TODO: register buffers with hw, handle error cases
+    }
+    mRegistered = true;
+
+    pthread_mutex_unlock(&mMutex);
+
+    return 0;
+}
+
+// This must only be called with mMutex held
+void Stream::unregisterBuffers_L()
+{
+    mRegistered = false;
+    mNumBuffers = 0;
+    delete [] mBuffers;
+    // TODO: unregister buffers from hw
+}
+
 } // namespace default_camera_hal
diff --git a/modules/camera/Stream.h b/modules/camera/Stream.h
index 9720289..521362e 100644
--- a/modules/camera/Stream.h
+++ b/modules/camera/Stream.h
@@ -31,18 +31,24 @@
         // validate that astream's parameters match this stream's parameters
         bool isValidReuseStream(int id, camera3_stream_t *s);
 
+        // Register buffers with hardware
+        int registerBuffers(const camera3_stream_buffer_set_t *buf_set);
+
         void setUsage(uint32_t usage);
         void setMaxBuffers(uint32_t max_buffers);
 
         int getType();
         bool isInputType();
         bool isOutputType();
-        bool getRegistered();
+        bool isRegistered();
 
         // This stream is being reused. Used in stream configuration passes
         bool mReuse;
 
     private:
+        // Clean up buffer state. must be called with mMutex held.
+        void unregisterBuffers_L();
+
         // The camera device id this stream belongs to
         const int mId;
         // Handle to framework's stream, used as a cookie for buffers
@@ -61,6 +67,10 @@
         uint32_t mMaxBuffers;
         // Buffers have been registered for this stream and are ready
         bool mRegistered;
+        // Array of handles to buffers currently in use by the stream
+        buffer_handle_t **mBuffers;
+        // Number of buffers in mBuffers
+        unsigned int mNumBuffers;
         // Lock protecting the Stream object for modifications
         pthread_mutex_t mMutex;
 };