Camera: fill in Camera3Device offline processing impl

Move shared method implementations to Camera3OutputUtils.cpp/h
Defined interfaces to handle Camera3Device/Camera3OfflineSession
behavior differences in Camera3OutputInterface.h.

Bug: 135142453
Test: N/A (not enough implementation yet)
Change-Id: I57476ca5a1edf69c02a22241ad776d6f02636033
diff --git a/services/camera/libcameraservice/device3/BufferUtils.h b/services/camera/libcameraservice/device3/BufferUtils.h
new file mode 100644
index 0000000..452a908
--- /dev/null
+++ b/services/camera/libcameraservice/device3/BufferUtils.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA3_BUFFER_UTILS_H
+#define ANDROID_SERVERS_CAMERA3_BUFFER_UTILS_H
+
+#include <unordered_map>
+#include <mutex>
+#include <set>
+
+#include <cutils/native_handle.h>
+
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+
+// TODO: remove legacy camera3.h references
+#include "hardware/camera3.h"
+
+#include <device3/Camera3OutputInterface.h>
+
+namespace android {
+
+namespace camera3 {
+
+    struct BufferHasher {
+        size_t operator()(const buffer_handle_t& buf) const {
+            if (buf == nullptr)
+                return 0;
+
+            size_t result = 1;
+            result = 31 * result + buf->numFds;
+            for (int i = 0; i < buf->numFds; i++) {
+                result = 31 * result + buf->data[i];
+            }
+            return result;
+        }
+    };
+
+    struct BufferComparator {
+        bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
+            if (buf1->numFds == buf2->numFds) {
+                for (int i = 0; i < buf1->numFds; i++) {
+                    if (buf1->data[i] != buf2->data[i]) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+    };
+
+    // Per stream buffer native handle -> bufId map
+    typedef std::unordered_map<const buffer_handle_t, uint64_t,
+            BufferHasher, BufferComparator> BufferIdMap;
+
+    // streamId -> BufferIdMap
+    typedef std::unordered_map<int, BufferIdMap> BufferIdMaps;
+
+    // Map of inflight buffers sent along in capture requests.
+    // Key is composed by (frameNumber << 32 | streamId)
+    typedef std::unordered_map<uint64_t, buffer_handle_t*> InflightBufferMap;
+
+    // Map of inflight buffers dealt by requestStreamBuffers API
+    typedef std::unordered_map<uint64_t, std::pair<int32_t, buffer_handle_t*>> RequestedBufferMap;
+
+    // A struct containing all buffer tracking information like inflight buffers
+    // and buffer ID caches
+    class BufferRecords : public BufferRecordsInterface {
+
+    public:
+        BufferRecords() {}
+
+        BufferRecords(BufferRecords&& other) :
+                mBufferIdMaps(other.mBufferIdMaps),
+                mNextBufferId(other.mNextBufferId),
+                mInflightBufferMap(other.mInflightBufferMap),
+                mRequestedBufferMap(other.mRequestedBufferMap) {}
+
+        virtual ~BufferRecords() {}
+
+        // Helper methods to help moving buffer records
+        void takeInflightBufferMap(BufferRecords& other);
+        void takeRequestedBufferMap(BufferRecords& other);
+        void takeBufferCaches(BufferRecords& other, const std::vector<int32_t>& streams);
+
+        // method to extract buffer's unique ID
+        // return pair of (newlySeenBuffer?, bufferId)
+        virtual std::pair<bool, uint64_t> getBufferId(
+                const buffer_handle_t& buf, int streamId) override;
+
+        void tryCreateBufferCache(int streamId);
+
+        void removeInactiveBufferCaches(const std::set<int32_t>& activeStreams);
+
+        // Return the removed buffer ID if input cache is found.
+        // Otherwise return BUFFER_ID_NO_BUFFER
+        uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle);
+
+        // Clear all caches for input stream, but do not remove the stream
+        // Removed buffers' ID are returned
+        std::vector<uint64_t> clearBufferCaches(int streamId);
+
+        bool isStreamCached(int streamId);
+
+        // Return true if the input caches match what we have; otherwise false
+        bool verifyBufferIds(int32_t streamId, std::vector<uint64_t>& inBufIds);
+
+        // Get a vector of (frameNumber, streamId) pair of currently inflight
+        // buffers
+        void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
+
+        status_t pushInflightBuffer(int32_t frameNumber, int32_t streamId,
+                buffer_handle_t *buffer);
+
+        // Find a buffer_handle_t based on frame number and stream ID
+        virtual status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
+                /*out*/ buffer_handle_t **buffer) override;
+
+        // Pop inflight buffers based on pairs of (frameNumber,streamId)
+        void popInflightBuffers(const std::vector<std::pair<int32_t, int32_t>>& buffers);
+
+        // Get a vector of bufferId of currently inflight buffers
+        void getInflightRequestBufferKeys(std::vector<uint64_t>* out);
+
+        // Register a bufId (streamId, buffer_handle_t) to inflight request buffer
+        virtual status_t pushInflightRequestBuffer(
+                uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) override;
+
+        // Find a buffer_handle_t based on bufferId
+        virtual status_t popInflightRequestBuffer(uint64_t bufferId,
+                /*out*/ buffer_handle_t** buffer,
+                /*optional out*/ int32_t* streamId = nullptr) override;
+
+    private:
+        std::mutex mBufferIdMapLock;
+        BufferIdMaps mBufferIdMaps;
+        uint64_t mNextBufferId = 1; // 0 means no buffer
+
+        std::mutex mInflightLock;
+        InflightBufferMap mInflightBufferMap;
+
+        std::mutex mRequestedBuffersLock;
+        RequestedBufferMap mRequestedBufferMap;
+    }; // class BufferRecords
+
+    static const uint64_t BUFFER_ID_NO_BUFFER = 0;
+
+    camera3_buffer_status_t mapHidlBufferStatus(
+            hardware::camera::device::V3_2::BufferStatus status);
+} // namespace camera3
+
+} // namespace android
+
+#endif