Move Codec2-related code from hardware/google/av
Test: None
Bug: 112362730
Change-Id: Ie2f8ff431d65c40333f267ab9877d47089adeea4
diff --git a/media/codec2/vndk/include/C2AllocatorGralloc.h b/media/codec2/vndk/include/C2AllocatorGralloc.h
new file mode 100644
index 0000000..05d989e
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorGralloc.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
+
+#include <functional>
+
+#include <C2Buffer.h>
+
+namespace android {
+
+/**
+ * Unwrap the native handle from a Codec2 handle allocated by C2AllocatorGralloc.
+ *
+ * @param handle a handle allocated by C2AllocatorGralloc. This includes handles returned for a
+ * graphic block allocation handle returned.
+ *
+ * @return a new NON-OWNING native handle that must be deleted using native_handle_delete.
+ */
+native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle);
+
+/**
+ * Wrap the gralloc handle and metadata into Codec2 handle recognized by
+ * C2AllocatorGralloc.
+ *
+ * @return a new NON-OWNING C2Handle that must be deleted using native_handle_delete.
+ */
+C2Handle *WrapNativeCodec2GrallocHandle(
+ const native_handle_t *const handle,
+ uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
+ uint32_t generation = 0, uint64_t igbp_id = 0, uint32_t igbp_slot = 0);
+
+/**
+ * \todo Get this from the buffer
+ */
+void _UnwrapNativeCodec2GrallocMetadata(
+ const C2Handle *const handle,
+ uint32_t *width, uint32_t *height, uint32_t *format, uint64_t *usage, uint32_t *stride,
+ uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot);
+
+class C2AllocatorGralloc : public C2Allocator {
+public:
+ virtual id_t getId() const override;
+
+ virtual C2String getName() const override;
+
+ virtual std::shared_ptr<const Traits> getTraits() const override;
+
+ virtual c2_status_t newGraphicAllocation(
+ uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
+ std::shared_ptr<C2GraphicAllocation> *allocation) override;
+
+ virtual c2_status_t priorGraphicAllocation(
+ const C2Handle *handle,
+ std::shared_ptr<C2GraphicAllocation> *allocation) override;
+
+ C2AllocatorGralloc(id_t id, bool bufferQueue = false);
+
+ c2_status_t status() const;
+
+ virtual ~C2AllocatorGralloc() override;
+
+ static bool isValid(const C2Handle* const o);
+
+private:
+ class Impl;
+ Impl *mImpl;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
diff --git a/media/codec2/vndk/include/C2AllocatorIon.h b/media/codec2/vndk/include/C2AllocatorIon.h
new file mode 100644
index 0000000..1b2051f
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorIon.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
+
+#include <functional>
+#include <list>
+#include <mutex>
+#include <tuple>
+#include <unordered_map>
+
+#include <C2Buffer.h>
+
+namespace android {
+
+class C2AllocatorIon : public C2Allocator {
+public:
+ // Usage mapper function used by the allocator
+ // (usage, capacity) => (align, heapMask, flags)
+ //
+ // capacity is aligned to the default block-size (defaults to page size) to reduce caching
+ // overhead
+ typedef std::function<c2_status_t(C2MemoryUsage, size_t,
+ /* => */ size_t*, unsigned*, unsigned*)> UsageMapperFn;
+
+ virtual id_t getId() const override;
+
+ virtual C2String getName() const override;
+
+ virtual std::shared_ptr<const Traits> getTraits() const override;
+
+ virtual c2_status_t newLinearAllocation(
+ uint32_t capacity, C2MemoryUsage usage,
+ std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+ virtual c2_status_t priorLinearAllocation(
+ const C2Handle *handle,
+ std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+ C2AllocatorIon(id_t id);
+
+ virtual c2_status_t status() const { return mInit; }
+
+ virtual ~C2AllocatorIon() override;
+
+ static bool isValid(const C2Handle* const o);
+
+ /**
+ * Updates the usage mapper for subsequent new allocations, as well as the supported
+ * minimum and maximum usage masks and default block-size to use for the mapper.
+ *
+ * \param mapper this method is called to map Codec 2.0 buffer usage to ion flags
+ * required by the ion device
+ * \param minUsage minimum buffer usage required for supported allocations (defaults to 0)
+ * \param maxUsage maximum buffer usage supported by the ion allocator (defaults to SW_READ
+ * | SW_WRITE)
+ * \param blockSize alignment used prior to calling |mapper| for the buffer capacity.
+ * This also helps reduce the size of cache required for caching mapper results.
+ * (defaults to the page size)
+ */
+ void setUsageMapper(
+ const UsageMapperFn &mapper, uint64_t minUsage, uint64_t maxUsage, uint64_t blockSize);
+
+private:
+ c2_status_t mapUsage(C2MemoryUsage usage, size_t size,
+ /* => */ size_t *align, unsigned *heapMask, unsigned *flags);
+
+ c2_status_t mInit;
+ int mIonFd;
+
+ // this locks mTraits, mBlockSize, mUsageMapper, mUsageMapperLru and mUsageMapperCache
+ mutable std::mutex mUsageMapperLock;
+ std::shared_ptr<const Traits> mTraits;
+ size_t mBlockSize;
+ UsageMapperFn mUsageMapper;
+ typedef std::pair<uint64_t, size_t> MapperKey;
+ struct MapperKeyHash {
+ std::size_t operator()(const MapperKey &) const;
+ };
+ typedef std::tuple<size_t, unsigned, unsigned, c2_status_t> MapperValue;
+ typedef std::pair<MapperKey, MapperValue> MapperKeyValue;
+ typedef std::list<MapperKeyValue>::iterator MapperKeyValuePointer;
+ std::list<MapperKeyValue> mUsageMapperLru;
+ std::unordered_map<MapperKey, MapperKeyValuePointer, MapperKeyHash> mUsageMapperCache;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
diff --git a/media/codec2/vndk/include/C2BqBufferPriv.h b/media/codec2/vndk/include/C2BqBufferPriv.h
new file mode 100644
index 0000000..9271a71
--- /dev/null
+++ b/media/codec2/vndk/include/C2BqBufferPriv.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 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 STAGEFRIGHT_CODEC2_BQ_BUFFER_PRIV_H_
+#define STAGEFRIGHT_CODEC2_BQ_BUFFER_PRIV_H_
+
+#include <functional>
+
+#include <C2Buffer.h>
+#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
+
+class C2BufferQueueBlockPool : public C2BlockPool {
+public:
+ C2BufferQueueBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
+
+ virtual ~C2BufferQueueBlockPool() override;
+
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ };
+
+ virtual local_id_t getLocalId() const override {
+ return mLocalId;
+ };
+
+ virtual c2_status_t fetchGraphicBlock(
+ uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ C2MemoryUsage usage,
+ std::shared_ptr<C2GraphicBlock> *block /* nonnull */) override;
+
+ typedef std::function<void(uint64_t producer, int32_t slot, int64_t nsecs)> OnRenderCallback;
+
+ /**
+ * Sets render callback.
+ *
+ * \param renderCallbak callback to call for all dequeue buffer.
+ */
+ virtual void setRenderCallback(const OnRenderCallback &renderCallback = OnRenderCallback());
+
+ /**
+ * Configures an IGBP in order to create blocks. A newly created block is
+ * dequeued from the configured IGBP. Unique Id of IGBP and the slot number of
+ * blocks are passed via native_handle. Managing IGBP is responsibility of caller.
+ * When IGBP is not configured, block will be created via allocator.
+ * Since zero is not used for Unique Id of IGBP, if IGBP is not configured or producer
+ * is configured as nullptr, unique id which is bundled in native_handle is zero.
+ *
+ * \param producer the IGBP, which will be used to fetch blocks
+ */
+ virtual void configureProducer(const android::sp<android::HGraphicBufferProducer> &producer);
+
+private:
+ const std::shared_ptr<C2Allocator> mAllocator;
+ const local_id_t mLocalId;
+
+ class Impl;
+ std::shared_ptr<Impl> mImpl;
+
+ friend struct C2BufferQueueBlockPoolData;
+};
+
+#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/codec2/vndk/include/C2BufferPriv.h b/media/codec2/vndk/include/C2BufferPriv.h
new file mode 100644
index 0000000..d0b9152
--- /dev/null
+++ b/media/codec2/vndk/include/C2BufferPriv.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
+#define STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
+
+#include <functional>
+
+#include <C2Buffer.h>
+#include <android/hardware/media/bufferpool/1.0/IAccessor.h>
+
+class C2BasicLinearBlockPool : public C2BlockPool {
+public:
+ explicit C2BasicLinearBlockPool(const std::shared_ptr<C2Allocator> &allocator);
+
+ virtual ~C2BasicLinearBlockPool() override = default;
+
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ }
+
+ virtual local_id_t getLocalId() const override {
+ return BASIC_LINEAR;
+ }
+
+ virtual c2_status_t fetchLinearBlock(
+ uint32_t capacity,
+ C2MemoryUsage usage,
+ std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
+
+ // TODO: fetchCircularBlock
+
+private:
+ const std::shared_ptr<C2Allocator> mAllocator;
+};
+
+class C2BasicGraphicBlockPool : public C2BlockPool {
+public:
+ explicit C2BasicGraphicBlockPool(const std::shared_ptr<C2Allocator> &allocator);
+
+ virtual ~C2BasicGraphicBlockPool() override = default;
+
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ }
+
+ virtual local_id_t getLocalId() const override {
+ return BASIC_GRAPHIC;
+ }
+
+ virtual c2_status_t fetchGraphicBlock(
+ uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ C2MemoryUsage usage,
+ std::shared_ptr<C2GraphicBlock> *block /* nonnull */) override;
+
+private:
+ const std::shared_ptr<C2Allocator> mAllocator;
+};
+
+class C2PooledBlockPool : public C2BlockPool {
+public:
+ C2PooledBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
+
+ virtual ~C2PooledBlockPool() override;
+
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ }
+
+ virtual local_id_t getLocalId() const override {
+ return mLocalId;
+ }
+
+ virtual c2_status_t fetchLinearBlock(
+ uint32_t capacity,
+ C2MemoryUsage usage,
+ std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
+
+ virtual c2_status_t fetchGraphicBlock(
+ uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ C2MemoryUsage usage,
+ std::shared_ptr<C2GraphicBlock> *block) override;
+
+ /**
+ * Retrieves the connection Id for underlying bufferpool
+ */
+ int64_t getConnectionId();
+
+ /**
+ * Retrieves the accessor which is used by underlying bufferpool. (It can be
+ * passed to receiving process.)
+ *
+ * \param accessor IAccessor will be written to this out parameter.
+ *
+ * \return true IAcessor is writen successfully.
+ * \return false IAccessor is not written.
+ */
+ bool getAccessor(android::sp<android::hardware::media::bufferpool::V1_0::IAccessor> *accessor);
+
+private:
+ const std::shared_ptr<C2Allocator> mAllocator;
+ const local_id_t mLocalId;
+
+ class Impl;
+ std::unique_ptr<Impl> mImpl;
+};
+
+#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/codec2/vndk/include/C2ComponentFactory.h b/media/codec2/vndk/include/C2ComponentFactory.h
new file mode 100644
index 0000000..f6d8b98
--- /dev/null
+++ b/media/codec2/vndk/include/C2ComponentFactory.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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 STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
+#define STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
+
+#include <C2Component.h>
+
+#include <functional>
+#include <memory>
+
+/**
+ * Component factory object that enables to create a component and/or interface from a dynamically
+ * linked library. This is needed because the component/interfaces are managed objects, but we
+ * cannot safely create a managed object and pass it in C.
+ *
+ * Components/interfaces typically inherit from std::enable_shared_from_this, but C requires
+ * passing simple pointer, and shared_ptr constructor needs to know the class to be constructed
+ * derives from enable_shared_from_this.
+ *
+ */
+class C2ComponentFactory {
+public:
+ typedef std::function<void(::C2Component*)> ComponentDeleter;
+ typedef std::function<void(::C2ComponentInterface*)> InterfaceDeleter;
+
+ /**
+ * Creates a component.
+ *
+ * This method SHALL return within 100ms.
+ *
+ * \param id component ID for the created component
+ * \param component shared pointer where the created component is stored. Cleared on
+ * failure and updated on success.
+ *
+ * \retval C2_OK the component was created successfully
+ * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
+ * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
+ *
+ * \retval C2_NO_MEMORY not enough memory to create the component
+ */
+ virtual c2_status_t createComponent(
+ c2_node_id_t id, std::shared_ptr<C2Component>* const component,
+ ComponentDeleter deleter = std::default_delete<C2Component>()) = 0;
+
+ /**
+ * Creates a component interface.
+ *
+ * This method SHALL return within 100ms.
+ *
+ * \param id component interface ID for the created interface
+ * \param interface shared pointer where the created interface is stored. Cleared on
+ * failure and updated on success.
+ *
+ * \retval C2_OK the component interface was created successfully
+ * \retval C2_TIMED_OUT could not create the component interface within the time limit
+ * (unexpected)
+ * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
+ * (unexpected)
+ *
+ * \retval C2_NO_MEMORY not enough memory to create the component interface
+ */
+ virtual c2_status_t createInterface(
+ c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+ InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) = 0;
+
+ virtual ~C2ComponentFactory() = default;
+
+ typedef ::C2ComponentFactory* (*CreateCodec2FactoryFunc)(void);
+ typedef void (*DestroyCodec2FactoryFunc)(::C2ComponentFactory*);
+};
+
+
+#endif // STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
diff --git a/media/codec2/vndk/include/C2Debug.h b/media/codec2/vndk/include/C2Debug.h
new file mode 100644
index 0000000..af1cdab
--- /dev/null
+++ b/media/codec2/vndk/include/C2Debug.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_DEBUG_H_
+#define C2UTILS_DEBUG_H_
+
+#include <util/C2Debug-log.h>
+
+// To allow arbitrary ordering of C2Debug.h and API headers and to keep debug utilities separately
+// from the API definitions, we provide API header specific debug headers.
+#ifdef C2PARAM_H_
+#include <util/C2Debug-param.h>
+#endif
+
+#endif // C2UTILS_DEBUG_H_
diff --git a/media/codec2/vndk/include/C2ErrnoUtils.h b/media/codec2/vndk/include/C2ErrnoUtils.h
new file mode 100644
index 0000000..5b995f6
--- /dev/null
+++ b/media/codec2/vndk/include/C2ErrnoUtils.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016 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 STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+#define STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+
+#include <errno.h>
+#include <C2.h>
+
+// standard ERRNO mappings
+template<int N> constexpr c2_status_t _c2_errno2status_impl();
+template<> constexpr c2_status_t _c2_errno2status_impl<0>() { return C2_OK; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EINVAL>() { return C2_BAD_VALUE; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EACCES>() { return C2_REFUSED; }
+template<> constexpr c2_status_t _c2_errno2status_impl<EPERM>() { return C2_REFUSED; }
+template<> constexpr c2_status_t _c2_errno2status_impl<ENOMEM>() { return C2_NO_MEMORY; }
+
+// map standard errno-s to the equivalent c2_status_t
+template<int... N> struct _c2_map_errno_impl;
+template<int E, int ... N> struct _c2_map_errno_impl<E, N...> {
+ static c2_status_t map(int result) {
+ if (result == E) {
+ return _c2_errno2status_impl <E>();
+ } else {
+ return _c2_map_errno_impl<N...>::map(result);
+ }
+ }
+};
+template<> struct _c2_map_errno_impl<> {
+ static c2_status_t map(int result) {
+ return result == 0 ? C2_OK : C2_CORRUPTED;
+ }
+};
+
+template<int... N>
+c2_status_t c2_map_errno(int result) {
+ return _c2_map_errno_impl<N...>::map(result);
+}
+
+#endif // STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
+
diff --git a/media/codec2/vndk/include/C2PlatformStorePluginLoader.h b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
new file mode 100644
index 0000000..4c10643
--- /dev/null
+++ b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2018, 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 STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
+
+#define STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
+
+#include <memory>
+
+#include <utils/Mutex.h>
+
+#include <C2.h>
+#include <C2Buffer.h>
+
+/**
+ * Extern C interface for creating block pool from platform store extension.
+ *
+ * \param alloctorId the ID of the backing allocator type.
+ * \parem blockPoolId the ID of created block pool.
+ *
+ * \return pointer of created C2BlockPool, nullptr on error.
+ */
+typedef ::C2BlockPool* (*CreateBlockPoolFunc)(::C2Allocator::id_t, ::C2BlockPool::local_id_t);
+
+/**
+ * Extern C interface for creating allocator from platform store extension.
+ *
+ * \param alloctorId the ID of the allocator to create.
+ * \param status the returned status from creating allocator.
+ *
+ * \return pointer of created C2Allocator, nullptr on error.
+ */
+typedef ::C2Allocator* (*CreateAllocatorFunc)(::C2Allocator::id_t, ::c2_status_t*);
+
+class C2PlatformStorePluginLoader {
+public:
+ static const std::unique_ptr<C2PlatformStorePluginLoader>& GetInstance();
+ ~C2PlatformStorePluginLoader();
+
+ /**
+ * Creates block pool from platform store extension.
+ *
+ * \param alloctorId the ID of the backing allocator type.
+ * \param blockPoolId the ID of created block pool.
+ * \param pool shared pointer where the created block pool is stored.
+ *
+ * \retval C2_OK the block pool was created successfully.
+ * \retval C2_NOT_FOUND the extension symbol was not found.
+ * \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
+ */
+ c2_status_t createBlockPool(::C2Allocator::id_t allocatorId,
+ ::C2BlockPool::local_id_t blockPoolId,
+ std::shared_ptr<C2BlockPool>* pool);
+
+ /**
+ * Creates allocator from platform store extension.
+ *
+ * Note that this allocator is not created as shared singleton as C2AllocatorStore does, because
+ * C interface only allows raw pointer transmission for extension.
+ *
+ * \param alloctorId the ID of the allocator to create.
+ * \param allocator shared pointer where the created allocator is stored.
+ *
+ * \retval C2_OK the allocator was created successfully.
+ * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected)
+ * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected)
+ * \retval C2_NOT_FOUND the extension symbol was not found.
+ * \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
+ * \retval C2_NO_MEMORY not enough memory to create the allocator
+ */
+ c2_status_t createAllocator(::C2Allocator::id_t allocatorId,
+ std::shared_ptr<C2Allocator>* const allocator);
+
+private:
+ explicit C2PlatformStorePluginLoader(const char *libPath);
+
+ static android::Mutex sMutex;
+ static std::unique_ptr<C2PlatformStorePluginLoader> sInstance;
+
+ void *mLibHandle;
+ CreateBlockPoolFunc mCreateBlockPool;
+ CreateAllocatorFunc mCreateAllocator;
+};
+
+#endif // STAGEFRIGHT_C2_PLATFORM_STORE_PLUGIN_LOADER_H_
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
new file mode 100644
index 0000000..f31282c
--- /dev/null
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 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 STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+#define STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+
+#include <C2Component.h>
+#include <C2ComponentFactory.h>
+
+#include <memory>
+
+namespace android {
+
+/**
+ * Returns the platform allocator store.
+ * \retval nullptr if the platform allocator store could not be obtained
+ */
+std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
+
+/**
+ * Platform allocator store IDs
+ */
+class C2PlatformAllocatorStore : public C2AllocatorStore {
+public:
+ enum : id_t {
+ /**
+ * ID of the ion backed platform allocator.
+ *
+ * C2Handle consists of:
+ * fd shared ion buffer handle
+ * int size (lo 32 bits)
+ * int size (hi 32 bits)
+ * int magic '\xc2io\x00'
+ */
+ ION = PLATFORM_START,
+
+ /**
+ * ID of the gralloc backed platform allocator.
+ *
+ * C2Handle layout is not public. Use C2AllocatorGralloc::UnwrapNativeCodec2GrallocHandle
+ * to get the underlying gralloc handle from a C2Handle, and WrapNativeCodec2GrallocHandle
+ * to create a C2Handle from a gralloc handle - for C2Allocator::priorAllocation.
+ */
+ GRALLOC,
+
+ /**
+ * ID of the bufferqueue backed platform allocator.
+ *
+ * C2Handle layout is not public. Use C2AllocatorGralloc::UnwrapNativeCodec2GrallocHandle
+ * to get the underlying handle from a C2Handle, and WrapNativeCodec2GrallocHandle
+ * to create a C2Handle from a handle - for C2Allocator::priorAllocation.
+ */
+ BUFFERQUEUE,
+
+ /**
+ * ID of indicating the end of platform allocator definition.
+ *
+ * \note always put this macro in the last place.
+ *
+ * Extended platform store plugin should use this macro as the start ID of its own allocator
+ * types.
+ */
+ PLATFORM_END,
+ };
+};
+
+/**
+ * Retrieves a block pool for a component.
+ *
+ * \param id the local ID of the block pool
+ * \param component the component using the block pool (must be non-null)
+ * \param pool pointer to where the obtained block pool shall be stored on success. nullptr
+ * will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the block pool does not exist
+ * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
+ * possible for basic pools)
+ * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
+ * \retval C2_REFUSED no permission to complete any required allocation (this return value is only
+ * possible for basic pools)
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
+ * this return value is only possible for basic pools)
+ */
+c2_status_t GetCodec2BlockPool(
+ C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Creates a block pool.
+ * \param allocatorId the allocator ID which is used to allocate blocks
+ * \param component the component using the block pool (must be non-null)
+ * \param pool pointer to where the created block pool shall be store on success.
+ * nullptr will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the allocator does not exist
+ * \retval C2_NO_MEMORY not enough memory to create a block pool
+ */
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorStore::id_t allocatorId,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Returns the platform component store.
+ * \retval nullptr if the platform component store could not be obtained
+ */
+std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore();
+
+/**
+ * Sets the preferred component store in this process for the sole purpose of accessing its
+ * interface. If this is not called, the default IComponentStore HAL (if exists) is the preferred
+ * store for this purpose. If the default IComponentStore HAL is not present, the platform
+ * component store is used.
+ */
+void SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> store);
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/codec2/vndk/include/android-C2Debug-log.h b/media/codec2/vndk/include/android-C2Debug-log.h
new file mode 100644
index 0000000..5910228
--- /dev/null
+++ b/media/codec2/vndk/include/android-C2Debug-log.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_ANDROID_DEBUG_LOG_H_
+#define C2UTILS_ANDROID_DEBUG_LOG_H_
+
+/*
+ * Android provides logging and debug macros. Redefine them with C2 prefix and add support for
+ * opting out of verbose logs.
+ */
+
+#ifdef C2_LOG_TAG
+#define LOG_TAG C2_LOG_TAG
+#endif
+
+#include <android-base/logging.h>
+
+#ifdef C2_LOG_VERBOSE
+#define C2_LOG(LEVEL) LOG(::android::base::LEVEL)
+#else
+/**
+ * Use as follows:
+ *
+ * #define C2_LOG_TAG "tag"
+ * //#define C2_LOG_VERBOSE // enable verbose logs in this file
+ * #include <C2Debug.h>
+ *
+ * C2_LOG(DEBUG) << expr ...;
+ *
+ * Log levels are: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL (aborts).
+ *
+ * No endl is required.
+ */
+#define C2_LOG(LEVEL) \
+ (::android::base::LEVEL != ::android::base::VERBOSE) && LOG(::android::base::LEVEL)
+#endif
+
+#define C2_CHECK CHECK
+#define C2_CHECK_LT CHECK_LT
+#define C2_CHECK_LE CHECK_LE
+#define C2_CHECK_EQ CHECK_EQ
+#define C2_CHECK_GE CHECK_GE
+#define C2_CHECK_GT CHECK_GT
+#define C2_CHECK_NE CHECK_NE
+
+#define C2_DCHECK DCHECK
+#define C2_DCHECK_LT DCHECK_LT
+#define C2_DCHECK_LE DCHECK_LE
+#define C2_DCHECK_EQ DCHECK_EQ
+#define C2_DCHECK_GE DCHECK_GE
+#define C2_DCHECK_GT DCHECK_GT
+#define C2_DCHECK_NE DCHECK_NE
+
+#endif // C2UTILS_ANDROID_DEBUG_LOG_H_
diff --git a/media/codec2/vndk/include/util/C2Debug-base.h b/media/codec2/vndk/include/util/C2Debug-base.h
new file mode 100644
index 0000000..a040e42
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-base.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_DEBUG_BASE_H_
+#define C2UTILS_DEBUG_BASE_H_
+
+#include <iostream>
+
+/**
+ * Debug print utilities for Codec 2.0 base objects.
+ */
+
+#define C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(type) \
+const char *asString(type i, const char *def = "??"); \
+inline std::ostream& operator<<(std::ostream& os, const type &i) { \
+ return os << asString(i); \
+}
+
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(c2_status_t)
+
+
+#endif // C2UTILS_DEBUG_BASE_H_
+
diff --git a/media/codec2/vndk/include/util/C2Debug-interface.h b/media/codec2/vndk/include/util/C2Debug-interface.h
new file mode 100644
index 0000000..3f31875
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-interface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_DEBUG_INTERFACE_H_
+#define C2UTILS_DEBUG_INTERFACE_H_
+
+#include <util/C2Debug-base.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <iostream>
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedRange<T> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<T> &i);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+
+#endif // C2UTILS_DEBUG_INTERFACE_H_
diff --git a/media/codec2/vndk/include/util/C2Debug-log.h b/media/codec2/vndk/include/util/C2Debug-log.h
new file mode 100644
index 0000000..195c4c1
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-log.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_DEBUG_LOG_H_
+#define C2UTILS_DEBUG_LOG_H_
+
+// Platform specific debug utilities
+#ifdef __ANDROID__
+#include <android-C2Debug-log.h>
+#else
+// TODO: implement base debug utils
+#endif
+
+#endif // C2UTILS_DEBUG_LOG_H_
diff --git a/media/codec2/vndk/include/util/C2Debug-param.h b/media/codec2/vndk/include/util/C2Debug-param.h
new file mode 100644
index 0000000..e1c1de0
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2Debug-param.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_DEBUG_PARAM_H_
+#define C2UTILS_DEBUG_PARAM_H_
+
+#include <C2Param.h>
+#include <util/C2Debug-base.h>
+
+#include <iostream>
+
+/**
+ * Debug/print declarations for objects defined in C2Param.h
+ */
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(C2FieldDescriptor::type_t)
+
+std::ostream& operator<<(std::ostream& os, const C2Param::CoreIndex &i);
+std::ostream& operator<<(std::ostream& os, const C2Param::Type &i);
+std::ostream& operator<<(std::ostream& os, const C2Param::Index &i);
+std::ostream& operator<<(std::ostream& os, const _C2FieldId &i);
+std::ostream& operator<<(std::ostream& os, const C2FieldDescriptor &i);
+std::ostream& operator<<(std::ostream& os, const C2ParamField &i);
+
+#endif // C2UTILS_DEBUG_PARAM_H_
diff --git a/media/codec2/vndk/include/util/C2InterfaceHelper.h b/media/codec2/vndk/include/util/C2InterfaceHelper.h
new file mode 100644
index 0000000..bfb43af
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2InterfaceHelper.h
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_INTERFACE_HELPER_H_
+#define C2UTILS_INTERFACE_HELPER_H_
+
+#include <C2Component.h>
+#include <util/C2InterfaceUtils.h>
+
+#include <map>
+#include <mutex>
+#include <vector>
+
+#include <stddef.h>
+
+/**
+ * Interface Helper
+ */
+using C2R = C2SettingResultsBuilder;
+
+template<typename T, bool E=std::is_enum<T>::value>
+struct _c2_reduce_enum_to_underlying_type {
+ typedef T type;
+};
+
+template<typename T>
+struct _c2_reduce_enum_to_underlying_type<T, true> {
+ typedef typename std::underlying_type<T>::type type;
+};
+
+/**
+ * Helper class to implement parameter reflectors. This class is dynamic and is designed to be
+ * shared by multiple interfaces. This allows interfaces to add structure descriptors as needed.
+ */
+class C2ReflectorHelper : public C2ParamReflector {
+public:
+ C2ReflectorHelper() = default;
+ virtual ~C2ReflectorHelper() = default;
+ virtual std::unique_ptr<C2StructDescriptor> describe(
+ C2Param::CoreIndex paramIndex) const override;
+
+ /**
+ * Adds support for describing the given parameters.
+ *
+ * \param Params types of codec 2.0 structs (or parameters) to describe
+ */
+ template<typename... Params>
+ C2_INLINE void addStructDescriptors() {
+ std::vector<C2StructDescriptor> structs;
+ addStructDescriptors(structs, (_Tuple<Params...> *)nullptr);
+ }
+
+ /**
+ * Adds support for describing a specific struct.
+ *
+ * \param strukt descriptor for the struct that will be moved out.
+ */
+ void addStructDescriptor(C2StructDescriptor &&strukt);
+
+private:
+ template<typename... Params>
+ class C2_HIDE _Tuple { };
+
+ /**
+ * Adds support for describing the given descriptors.
+ *
+ * \param structs List of structure descriptors to add support for
+ */
+ void addStructDescriptors(
+ std::vector<C2StructDescriptor> &structs, _Tuple<> *);
+
+ /**
+ * Utility method that adds support for describing the given descriptors in a recursive manner
+ * one structure at a time using a list of structure descriptors temporary.
+ *
+ * \param T the type of codec 2.0 struct to describe
+ * \param Params rest of the structs
+ * \param structs Temporary list of structure descriptors used to optimize the operation.
+ */
+ template<typename T, typename... Params>
+ C2_INLINE void addStructDescriptors(
+ std::vector<C2StructDescriptor> &structs, _Tuple<T, Params...> *) {
+ structs.emplace_back((T*)nullptr);
+ addStructDescriptors(structs, (_Tuple<Params...> *)nullptr);
+ }
+
+ mutable std::mutex _mMutex;
+ std::map<C2Param::CoreIndex, const C2StructDescriptor> _mStructs; ///< descriptors
+};
+
+/**
+ * Utility class that implements the codec 2.0 interface API-s for some parameters.
+ *
+ * This class must be subclassed.
+ */
+class C2InterfaceHelper {
+public:
+ /**
+ * Returns the base offset of a field at |offset| that could be part of an array or part of a
+ * sub-structure.
+ *
+ * This method does not do field size verification, e.g. if offset if obtained from a structure,
+ * it will not stop at the structure boundary - this is okay, as we just want the base offset
+ * here, which is the same.
+ */
+ static
+ size_t GetBaseOffset(const std::shared_ptr<C2ParamReflector> &reflector,
+ C2Param::CoreIndex index, size_t offset);
+
+ /**
+ * The interface helper class uses references to std::shared_ptr<T> config parameters.
+ * Internally, these need to be generalized to std::shared_ptr<C2Param> refs, but the cast is
+ * not allowed (as these are references). As such, this class never returns pointer to the
+ * shared_ptrs.
+ */
+ struct ParamRef {
+ template<typename T, typename enable=
+ typename std::enable_if<std::is_convertible<T, C2Param>::value>::type>
+ inline C2_HIDE ParamRef(std::shared_ptr<T> ¶m)
+ : _mRef(reinterpret_cast<std::shared_ptr<C2Param>*>(¶m)) { }
+
+ // used by comparison operator for containers
+ operator std::shared_ptr<C2Param> *() const { return _mRef; }
+
+ /**
+ * Returns a shared pointer to the parameter.
+ */
+ std::shared_ptr<C2Param> get() const { return *_mRef; }
+
+ private:
+ std::shared_ptr<C2Param> *_mRef;
+ };
+
+ /**
+ * Field helper.
+ *
+ * Contains additional information for the field: possible values, and currently supported
+ * values.
+ */
+ class FieldHelper {
+ public:
+ /**
+ * Creates helper for a field with given possible values.
+ *
+ * \param param parameter reference. The parameter does not have to be initialized at this
+ * point.
+ * \param field field identifier
+ * \param values possible values for the field
+ */
+ FieldHelper(const ParamRef ¶m, const _C2FieldId &field,
+ std::unique_ptr<C2FieldSupportedValues> &&values);
+
+ /**
+ * Creates a param-field identifier for this field. This method is called after the
+ * underlying parameter has been initialized.
+ *
+ * \aram index
+ *
+ * @return C2ParamField
+ */
+ C2ParamField makeParamField(C2Param::Index index) const;
+
+ /**
+ * Sets the currently supported values for this field.
+ *
+ * \param values currently supported values that will be moved out
+ */
+ void setSupportedValues(std::unique_ptr<C2FieldSupportedValues> &&values);
+
+ /**
+ * Gets the currently supported values for this field. This defaults to the possible values
+ * if currently supported values were never set.
+ */
+ const C2FieldSupportedValues *getSupportedValues() const;
+
+ /**
+ * Gets the possible values for this field.
+ */
+ const C2FieldSupportedValues *getPossibleValues() const;
+
+ protected:
+ // TODO: move to impl for safety
+ ParamRef mParam;
+ _C2FieldId mFieldId;
+ std::unique_ptr<C2FieldSupportedValues> mPossible;
+ std::unique_ptr<C2FieldSupportedValues> mSupported; ///< if different from possible
+ };
+
+ template<typename T>
+ struct C2_HIDE Param;
+ class ParamHelper;
+
+ /**
+ * Factory is an interface to get the parameter helpers from a std::shared_ptr<T> &.
+ */
+ class Factory {
+ // \todo this may be already in ParamHelper
+ virtual std::shared_ptr<C2ParamReflector> getReflector() const = 0;
+
+ virtual std::shared_ptr<ParamHelper> getParamHelper(const ParamRef ¶m) const = 0;
+
+ public:
+ virtual ~Factory() = default;
+
+ template<typename T>
+ Param<T> get(std::shared_ptr<T> ¶m, std::shared_ptr<T> altValue = nullptr) const {
+ return Param<T>(getParamHelper(ParamRef(param)),
+ altValue == nullptr ? param : altValue,
+ getReflector());
+ }
+ };
+
+ /**
+ * Typed field helper.
+ */
+ template<typename T>
+ struct Field {
+ /**
+ * Constructor.
+ *
+ * \param helper helper for this field
+ * \param index parameter index (this is needed as it is not available during parameter
+ * construction) \todo remove
+ */
+ Field(std::shared_ptr<FieldHelper> helper, C2Param::Index index);
+
+ bool supportsAtAll(T value) const {
+ return C2FieldSupportedValuesHelper<T>(*_mHelper->getPossibleValues()).supports(value);
+ }
+
+ bool supportsNow(T value) const {
+ return C2FieldSupportedValuesHelper<T>(*_mHelper->getSupportedValues()).supports(value);
+ }
+
+ /**
+ * Creates a conflict resolution suggestion builder for this field.
+ */
+ C2ParamFieldValuesBuilder<T> shouldBe() const;
+
+ /**
+ * Creates a currently supported values builder for this field. This is only supported
+ * for non-const fields to disallow setting supported values for dependencies.
+ */
+ C2ParamFieldValuesBuilder<T> mustBe();
+
+ operator C2ParamField() const {
+ return _mField;
+ }
+
+ // TODO
+ C2R validatePossible(const T &value __unused) const {
+ /// TODO
+ return C2R::Ok();
+ }
+
+ private:
+ std::shared_ptr<FieldHelper> _mHelper;
+ C2ParamField _mField;
+ };
+
+ class ParamHelper {
+ public:
+ ParamHelper(ParamRef param, C2StringLiteral name, C2StructDescriptor &&);
+ ParamHelper(ParamHelper &&);
+ ~ParamHelper();
+
+ /**
+ * Finds a field descriptor.
+ */
+ std::shared_ptr<FieldHelper> findField(size_t baseOffs, size_t baseSize) const;
+
+ /// returns the parameter ref for this parameter
+ const ParamRef ref() const;
+
+ /// returns the current value of this parameter as modifiable. The constness of this
+ /// object determines the constness of the returned value.
+ std::shared_ptr<C2Param> value();
+
+ /// returns the current value of this parameter as const
+ std::shared_ptr<const C2Param> value() const;
+
+ /**
+ * Performs a configuration change request for this parameter.
+ *
+ * \param value the value that is being assigned to this parameter.
+ * This could be pointing to the current value of the
+ * parameter. This must not change.
+ * \param mayBlock whether blocking is allowed
+ * \param endValue the resulting value
+ * \param factory parameter factory (to access dependencies)
+ * \param failures vector of failures to append any failures from this
+ * operation
+ *
+ * \retval C2_OK configuration was successful
+ * \retval C2_BAD_VALUE value is incorrect (TBD)
+ * \retval C2_NO_MEMORY not enough memory to perform the assignment
+ * \retval C2_TIMED_OUT configuration timed out
+ * \retval C2_BLOCKING configuration requires blocking to be allowed
+ * \retval C2_CORRUPTED interface is corrupted
+ */
+ c2_status_t trySet(
+ const C2Param *value, bool mayBlock,
+ bool *changed,
+ Factory &factory,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures);
+
+ /// returns parameter indices that depend on this parameter
+ const std::vector<C2Param::Index> getDownDependencies() const;
+
+ /// adds a dependent parameter
+ void addDownDependency(C2Param::Index index);
+
+ /// returns that parameter refs for parameters that depend on this
+ const std::vector<ParamRef> getDependenciesAsRefs() const;
+
+ /// returns and moves out stored struct descriptor
+ C2StructDescriptor retrieveStructDescriptor();
+
+ /// returns the name of this parameter
+ C2String name() const;
+
+ /// returns the index of this parameter
+ C2Param::Index index() const;
+
+ /// returns the parameter descriptor
+ std::shared_ptr<const C2ParamDescriptor> getDescriptor() const;
+
+ /**
+ * Validates param helper.
+ *
+ * For now, this fills field info for const params.
+ *
+ * \retval C2_CORRUPTED the parameter cannot be added as such
+ */
+ c2_status_t validate(const std::shared_ptr<C2ParamReflector> &reflector);
+
+ protected:
+ typedef C2ParamDescriptor::attrib_t attrib_t;
+ attrib_t& attrib();
+
+ /// sets the default value of this parameter
+ void setDefaultValue(std::shared_ptr<C2Param> default_);
+
+ /// sets the setter method
+ void setSetter(std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter);
+
+ /// sets the getter method
+ void setGetter(std::function<std::shared_ptr<C2Param>(bool)> getter);
+
+ /// sets the dependencies
+ void setDependencies(std::vector<C2Param::Index> indices, std::vector<ParamRef> refs);
+
+ /// sets the fields and their supported values
+ void setFields(std::vector<C2ParamFieldValues> &&fields);
+
+ /// build this into a final ParamHelper object
+ std::shared_ptr<ParamHelper> build();
+
+ class Impl;
+ std::unique_ptr<Impl> mImpl;
+ };
+
+ /**
+ * Typed parameter helper. This provides access to members as well as field helpers.
+ */
+ template<typename T>
+ struct C2_HIDE Param {
+ Param(
+ std::shared_ptr<ParamHelper> helper, std::shared_ptr<T> ¶m,
+ std::shared_ptr<C2ParamReflector> reflector)
+ : v(*param.get()),
+ _mTypedParam(param),
+ _mHelper(helper),
+ _mReflector(reflector) { }
+
+ template<typename S>
+ using FieldType = Field<
+ typename _c2_reduce_enum_to_underlying_type<
+ typename std::remove_const<
+ typename std::remove_extent<S>::type>::type>::type>;
+
+ template<typename S>
+ FieldType<S> F(S &field) {
+ size_t offs = (uintptr_t)&field - (uintptr_t)&get();
+ // this must fall either within sizeof(T) + FLEX_SIZE or param->size()
+ // size_t size = sizeof(field);
+ // mParam may be null
+ size_t baseSize = sizeof(typename std::remove_extent<S>::type);
+ size_t baseOffs = GetBaseOffset(
+ _mReflector, T::CORE_INDEX, offs - sizeof(C2Param));
+ if (~baseOffs == 0) {
+ // C2_LOG(FATAL) << "unknown field at offset " << offs << " size " << sizeof(S)
+ // << " base-size " << baseSize;
+ // __builtin_trap();
+ } else {
+ baseOffs += sizeof(C2Param);
+ }
+
+ std::shared_ptr<FieldHelper> helper = _mHelper->findField(baseOffs, baseSize);
+ return FieldType<S>(helper, _mTypedParam->index());
+ }
+
+ // const Param have const Fields; however, remove const from S
+ template<typename S>
+ const FieldType<S> F(S &field) const {
+ return const_cast<const FieldType<S>>(const_cast<Param *>(this)->F(field));
+ }
+
+ /// Returns a const ref value of this const param.
+ const T &get() const {
+ return *_mTypedParam.get();
+ }
+
+ /// Returns a modifiable ref value of this non-const param.
+ T &set() {
+ return *_mTypedParam.get();
+ }
+
+ /// Const-reference to the value.s
+ T const &v;
+
+ private:
+ std::shared_ptr<T> _mTypedParam;
+ std::shared_ptr<ParamHelper> _mHelper;
+ std::shared_ptr<C2ParamReflector> _mReflector;
+ };
+
+ template<typename T>
+ using C2P = Param<T>;
+
+ /**
+ * Templated move builder class for a parameter helper.
+ */
+ template<typename T>
+ class C2_HIDE ParamBuilder : private ParamHelper {
+ public:
+ /** Construct the parameter builder from minimal info required. */
+ ParamBuilder(std::shared_ptr<T> ¶m, C2StringLiteral name)
+ : ParamHelper(param, name, C2StructDescriptor((T*)nullptr)),
+ mTypedParam(¶m) {
+ attrib() = attrib_t::IS_PERSISTENT;
+ }
+
+ /** Makes this parameter required. */
+ inline ParamBuilder &required() {
+ attrib() |= attrib_t::IS_REQUIRED;
+ return *this;
+ }
+
+ /** Makes this parameter transient (not persistent). */
+ inline ParamBuilder &transient() {
+ attrib() &= ~attrib_t::IS_PERSISTENT;
+ return *this;
+ }
+
+ /** Makes this parameter hidden (not exposed in JAVA API). */
+ inline ParamBuilder &hidden() {
+ attrib() |= attrib_t::IS_HIDDEN;
+ return *this;
+ }
+
+ /** Makes this parameter internal (not exposed to query/settings). */
+ inline ParamBuilder &internal() {
+ attrib() |= attrib_t::IS_INTERNAL;
+ return *this;
+ }
+
+ /** Adds default value. Must be added exactly once. */
+ inline ParamBuilder &withDefault(std::shared_ptr<T> default_) {
+ // CHECK(!mDefaultValue);
+ // WARN_IF(!default_); // could be nullptr if OOM
+ // technically, this could be in the parent
+ *mTypedParam = std::shared_ptr<T>(T::From(C2Param::Copy(*default_).release()));
+ setDefaultValue(default_);
+ std::shared_ptr<T> *typedParam = mTypedParam;
+ setGetter([typedParam](bool) -> std::shared_ptr<C2Param> {
+ return std::static_pointer_cast<C2Param>(*typedParam);
+ });
+ return *this;
+ }
+
+ /** Adds default value. Must be added exactly once. */
+ inline ParamBuilder &withDefault(T *default_) {
+ return withDefault(std::shared_ptr<T>(default_));
+ }
+
+ /** Adds all fields to this parameter with their possible values. */
+ inline ParamBuilder &withFields(std::vector<C2ParamFieldValues> &&fields_) {
+ setFields(std::move(fields_));
+ return *this;
+ }
+
+ /**
+ * Adds a constant value (also as default). Must be added exactly once.
+ *
+ * Const parameters by definition have no dependencies.
+ */
+ inline ParamBuilder &withConstValue(std::shared_ptr<T> default_) {
+ attrib() |= attrib_t::IS_CONST;
+ setSetter([default_](
+ const C2Param *value, bool mayBlock __unused, bool *changed, Factory &) -> C2R {
+ *changed = false;
+ const T *typedValue = T::From(value);
+ if (typedValue == nullptr) {
+ return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+ }
+ if (*typedValue != *default_) {
+ return C2R::Corrupted(); // TODO ReadOnly(*default_);
+ }
+ *changed = false;
+ return C2R::Ok();
+ });
+ return withDefault(default_);
+ }
+
+ /** Adds constant value (also as default). Must be added exactly once. */
+ inline ParamBuilder &withConstValue(T *default_) {
+ return withConstValue(std::shared_ptr<T>(default_));
+ }
+
+ /**
+ * Use a strict setter.
+ *
+ * \param fn strict setter
+ * \param deps dependencies (references)
+ */
+ template<typename ... Deps>
+ inline ParamBuilder &withSetter(
+ C2R (*fn)(bool, const C2P<T> &, C2P<T> &, const C2P<Deps> &...),
+ std::shared_ptr<Deps>& ... deps) {
+ attrib() |= attrib_t::IS_STRICT;
+ std::shared_ptr<T> *typedParam = mTypedParam;
+ setSetter([typedParam, fn, &deps...](
+ const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R {
+ *changed = false;
+ const T *typedValue = T::From(value);
+ if (typedValue == nullptr) {
+ return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+ }
+ // Do copy-on-change for parameters in this helper so change can be detected by
+ // a change of the pointer. Do this by working on a proposed value.
+ std::shared_ptr<T> proposedValue =
+ std::shared_ptr<T>(T::From(C2Param::Copy(*value).release()));
+ if (proposedValue == nullptr) {
+ return C2R::NoMemory(value->index());
+ }
+ C2P<T> oldValue = factory.get(*typedParam);
+ // Get a parameter helper with value pointing to proposedValue
+ C2P<T> helper = factory.get(*typedParam, proposedValue);
+ C2R result = fn(mayBlock, oldValue, helper, factory.get(deps)...);
+
+ // If value changed, copy result to current value
+ if (helper.get() != *typedParam->get()) {
+ *typedParam = proposedValue;
+ *changed = true;
+ }
+ return result;
+ });
+ setDependencies(std::vector<C2Param::Index>{ deps->index()... },
+ std::vector<ParamRef>{ ParamRef(deps)... });
+ return *this;
+ }
+
+ /**
+ * Use a non-strict setter.
+ *
+ * \param fn non-strict setter
+ * \param deps dependencies (references)
+ */
+ template<typename ... Deps>
+ inline ParamBuilder &withSetter(
+ C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) {
+ std::shared_ptr<T> *typedParam = mTypedParam;
+ setSetter([typedParam, fn, &deps...](
+ const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R {
+ *changed = false;
+ const T *typedValue = T::From(value);
+ if (typedValue == nullptr) {
+ return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here.
+ }
+ // Do copy-on-change for parameters in this helper so change can be detected by
+ // a change of the pointer. Do this by working on a proposed value.
+ std::shared_ptr<T> proposedValue =
+ std::shared_ptr<T>(T::From(C2Param::Copy(*value).release()));
+ if (proposedValue == nullptr) {
+ return C2R::NoMemory(value->index());
+ }
+ // Get a parameter helper with value pointing to proposedValue
+ C2P<T> helper = factory.get(*typedParam, proposedValue);
+ C2R result = fn(mayBlock, helper, factory.get(deps)...);
+
+ // If value changed, copy result to current value
+ if (helper.get() != *typedParam->get()) {
+ *typedParam = proposedValue;
+ *changed = true;
+ }
+ return result;
+ });
+ setDependencies(std::vector<C2Param::Index>{ deps->index()... },
+ std::vector<ParamRef>{ ParamRef(deps)... });
+ return *this;
+ }
+
+ /**
+ * Marks this a calculated (read-only) field.
+ *
+ * \param fn non-strict setter (calculator)
+ * \param deps dependencies (references)
+ */
+ template<typename ... Deps>
+ inline ParamBuilder &calculatedAs(
+ C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) {
+ attrib() |= attrib_t::IS_READ_ONLY;
+ return withSetter(fn, std::forward<decltype(deps)>(deps)...);
+ }
+
+ inline std::shared_ptr<ParamHelper> build() {
+ return ParamHelper::build();
+ }
+
+ protected:
+ std::shared_ptr<T> *mTypedParam;
+ };
+
+ template<typename T>
+ static ParamBuilder<T> DefineParam(std::shared_ptr<T> ¶m, C2StringLiteral name) {
+ return ParamBuilder<T>(param, name);
+ }
+
+public:
+ c2_status_t query(
+ const std::vector<C2Param*> &stackParams,
+ const std::vector<C2Param::Index> &heapParamIndices,
+ c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2Param>>* const heapParams) const;
+
+ /**
+ * Helper implementing config calls as well as other configuration updates.
+ *
+ * This method is virtual, so implementations may provide wrappers around it (and perform
+ * actions just before and after a configuration).
+ *
+ * \param params
+ * \param mayBlock
+ * \param failures
+ * \param updateParams if true, the updated parameter values are copied back into the arguments
+ * passed in |params|
+ * \param changes pointed to a vector to receive settings with their values changed. If not
+ * null, settings with their values changed are added to this.
+ * \return result from config
+ */
+ virtual c2_status_t config(
+ const std::vector<C2Param*> ¶ms, c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures,
+ bool updateParams = true,
+ std::vector<std::shared_ptr<C2Param>> *changes = nullptr);
+
+ c2_status_t querySupportedParams(
+ std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const;
+
+ c2_status_t querySupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const;
+
+ std::shared_ptr<C2ReflectorHelper> getReflector() {
+ return mReflector;
+ }
+
+ typedef std::unique_lock<std::mutex> Lock;
+
+ /**
+ * Locks the interface and returns a lock. This lock must be unlocked or released without
+ * calling any other blocking call.
+ */
+ Lock lock() const;
+
+private:
+ void setInterfaceAddressBounds(uintptr_t start, uintptr_t end) {
+ // TODO: exclude this helper
+ (void)start;
+ (void)end;
+ }
+
+protected:
+ mutable std::mutex mMutex;
+ std::shared_ptr<C2ReflectorHelper> mReflector;
+ struct FactoryImpl;
+ std::shared_ptr<FactoryImpl> _mFactory;
+
+ C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector);
+
+ /**
+ * Adds a parameter to this interface.
+ * \note This method CHECKs.
+ *
+ * \param param parameter to add.
+ */
+ void addParameter(std::shared_ptr<ParamHelper> param);
+
+ /**
+ * Returns the dependency index for a parameter.
+ *
+ * \param ix the index of the parameter
+ */
+ size_t getDependencyIndex_l(C2Param::Index ix) const;
+
+ virtual ~C2InterfaceHelper() = default;
+
+ /**
+ * Sets subclass instance's address and size.
+ *
+ * \todo allow subclass to specify parameter address range directly (e.g. do not assume that
+ * they are local to the subclass instance)
+ *
+ * \param T type of the derived instance
+ * \param instance pointer to the derived instance
+ */
+ template<typename T>
+ inline C2_HIDE void setDerivedInstance(T *instance) {
+ setInterfaceAddressBounds((uintptr_t)instance, (uintptr_t)(instance + 1));
+ }
+
+ C2_DO_NOT_COPY(C2InterfaceHelper);
+};
+
+/**
+ * Creates a C2ParamFieldValuesBuilder class for a field of a parameter
+ *
+ * \param spParam a configuration parameter in an interface class subclassed from C2InterfaceHelper.
+ * \param field a field of such parameter
+ */
+#define C2F(spParam, field) \
+ C2ParamFieldValuesBuilder< \
+ typename _c2_reduce_enum_to_underlying_type< \
+ typename std::remove_reference< \
+ typename std::remove_extent< \
+ decltype(spParam->field)>::type>::type>::type>( \
+ C2ParamField(spParam.get(), &spParam->field))
+
+#endif // C2UTILS_INTERFACE_HELPER_H_
diff --git a/media/codec2/vndk/include/util/C2InterfaceUtils.h b/media/codec2/vndk/include/util/C2InterfaceUtils.h
new file mode 100644
index 0000000..e9037e5
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2InterfaceUtils.h
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (C) 2018 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 C2UTILS_INTERFACE_UTILS_H_
+#define C2UTILS_INTERFACE_UTILS_H_
+
+#include <C2Param.h>
+#include <C2Work.h>
+
+#include <cmath>
+#include <iterator>
+#include <limits>
+#include <type_traits>
+
+/**
+ * Helper class to map underlying types to C2Value types as well as to print field values. This is
+ * generally the same as simply the underlying type except for characters (STRING) and bytes (BLOB).
+ */
+template<typename T>
+struct C2_HIDE _C2FieldValueHelper {
+ typedef T ValueType;
+ inline static std::ostream& put(std::ostream &os, const C2Value::Primitive &p) {
+ return os << p.ref<T>();
+ }
+};
+
+template<>
+struct C2_HIDE _C2FieldValueHelper<uint8_t> {
+ typedef uint32_t ValueType;
+ static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
+};
+
+template<>
+struct C2_HIDE _C2FieldValueHelper<char> {
+ typedef int32_t ValueType;
+ static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
+};
+
+/**
+ * Supported value range utility for a field of a given type.
+ *
+ * This mimics C2FieldSupportedValue for RANGE type.
+ */
+template<typename T>
+class C2SupportedRange {
+ typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+//private:
+ constexpr static T MIN_VALUE = std::numeric_limits<T>::min();
+ constexpr static T MAX_VALUE = std::numeric_limits<T>::max();
+ constexpr static T MIN_STEP = std::is_floating_point<T>::value ? 0 : 1;
+
+public:
+ /**
+ * Constructs an empty range with no supported values.
+ *
+ * \note This is a specializated supported range representation that is only used for
+ * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+ */
+ inline static constexpr C2SupportedRange<T> None() {
+ return C2SupportedRange(MAX_VALUE, MIN_VALUE);
+ }
+
+ /**
+ * Constructs a range with all values supported.
+ */
+ inline static constexpr C2SupportedRange<T> Any() {
+ return C2SupportedRange(MIN_VALUE, MAX_VALUE);
+ }
+
+ /**
+ * Constructs a range with a single supported value.
+ *
+ * \param value the sole supported value
+ */
+ inline static constexpr C2SupportedRange<T> EqualTo(T value) {
+ return C2SupportedRange(value, value);
+ }
+
+ /**
+ * Constructs a range with supported values greater than a given value.
+ *
+ * \param value the given value
+ */
+ inline static C2SupportedRange<T> GreaterThan(T value) {
+ return (value == MAX_VALUE ? None() :
+ std::is_floating_point<T>::value ?
+ C2SupportedRange(std::nextafter(value, MAX_VALUE), MAX_VALUE) :
+ C2SupportedRange(value + MIN_STEP, MAX_VALUE));
+ }
+
+ /**
+ * Constructs a range with supported values greater than or equal to a given value.
+ *
+ * \param value the given value
+ */
+ inline static constexpr C2SupportedRange<T> GreaterThanOrEqualTo(T value) {
+ return C2SupportedRange(value, MAX_VALUE);
+ }
+
+ /**
+ * Constructs a range with supported values greater than or equal to (aka not less than) a given
+ * value.
+ *
+ * \param value the given value
+ */
+ inline static constexpr C2SupportedRange<T> NotLessThan(T value) {
+ return GreaterThanOrEqualTo(value);
+ }
+
+ /**
+ * Constructs a range with supported values less than or equal to a given value.
+ *
+ * \param value the given value
+ */
+ inline static constexpr C2SupportedRange<T> LessThanOrEqualTo(T value) {
+ return C2SupportedRange(MIN_VALUE, value);
+ }
+
+ /**
+ * Constructs a range with supported values less than or equal to (aka not greater than) a given
+ * value.
+ *
+ * \param value the given value
+ */
+ inline static constexpr C2SupportedRange<T> NotGreaterThan(T value) {
+ return LessThanOrEqualTo(value);
+ }
+
+ /**
+ * Constructs a range with supported values less than a given value.
+ *
+ * \param value the given value
+ */
+ inline static C2SupportedRange<T> LessThan(T value) {
+ return (value == MIN_VALUE ? None() :
+ std::is_floating_point<T>::value ?
+ C2SupportedRange(MIN_VALUE, std::nextafter(value, MIN_VALUE)) :
+ C2SupportedRange(MIN_VALUE, value - MIN_STEP));
+ }
+
+ /**
+ * Constructs a continuous or arithmetic range between two values.
+ *
+ * \param min the lower value
+ * \param max the higher value (if this is lower than |min| the range will be empty)
+ * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
+ * integer types, the constructed range is continuous)
+ */
+ inline static constexpr
+ C2SupportedRange<T> InRange(T min, T max, T step = MIN_STEP) {
+ return C2SupportedRange(min, max, step);
+ }
+
+ /**
+ * Constructs a range over a geometric series between two values.
+ *
+ * \param min the lower bound of the range. This value is always part of the constructed range
+ * as long as it is not greater than |max|.
+ * \param max the upper bound of the range. This value is only part of the constructed
+ * range if it is part of the geometric series.
+ * \param num the numerator of the geometric series.
+ * \param denom the denominator of the geometric series.
+ */
+ inline static constexpr
+ C2SupportedRange<T> InSeries(T min, T max, T num, T denom) {
+ return C2SupportedRange(min, max, 0, num, denom);
+ }
+
+ /**
+ * Constructs a range over a multiply-accumulate series between two values.
+ *
+ * \param min the lower bound of the range. This value is always part of the constructed range
+ * as long as it is not greater than |max|.
+ * \param max the upper bound of the range. This value is only part of the constructed
+ * range if it is part of the series.
+ * \param step the accumulator of the multiply-accumulate series
+ * \param num the numerator of the multiply-accumulate series.
+ * \param denom the denominator of the multiply-accumulate series.
+ */
+ inline static constexpr
+ C2SupportedRange<T> InMacSeries(T min, T max, T step, T num, T denom) {
+ return C2SupportedRange(min, max, step, num, denom);
+ }
+
+ /**
+ * Constructs a range from a generic C2FieldSupportedValues object. This will be an empty
+ * range if the supported values are not of RANGE type.
+ *
+ * \param values the supported values object
+ */
+ C2SupportedRange(const C2FieldSupportedValues &values);
+
+ /**
+ * Returns whether this range is empty.
+ */
+ inline constexpr bool isEmpty() const {
+ return _mMin > _mMax;
+ }
+
+ /**
+ * Returns whether this range is valid.
+ *
+ * Ranges are valid if they are continuous or monotonic.
+ */
+ inline constexpr bool isValid() const {
+ // TODO: handle overflow or negative series
+ return _mDenom > 0 && _mNum >= _mDenom && _mMin * (_mDenom - _mNum) < _mStep * _mDenom;
+ }
+
+ /**
+ * Returns whether a value is part of this range.
+ *
+ * \param value the value to check.
+ */
+ bool contains(T value) const;
+
+ /**
+ * Returns a new range that is the intersection of this range and another, if it is
+ * representable as a range object.
+ *
+ * \param limit the other range
+ */
+ C2SupportedRange<T> limitedTo(const C2SupportedRange<T> &limit) const;
+
+ /**
+ * Converts this object to a C2FieldSupportedValues object.
+ */
+ inline operator C2FieldSupportedValues() const {
+ return C2FieldSupportedValues(_mMin, _mMax, _mStep, _mNum, _mDenom);
+ }
+
+ /**
+ * Returns the lower bound and starting point of this range.
+ */
+ inline C2_HIDE constexpr T min() const { return _mMin; }
+
+ /**
+ * Returns the upper bound of this range.
+ */
+ inline C2_HIDE constexpr T max() const { return _mMax; }
+
+ /**
+ * Returns the step of this range.
+ */
+ inline C2_HIDE constexpr T step() const { return _mStep; }
+
+ /**
+ * Returns the numerator of this range.
+ */
+ inline C2_HIDE constexpr T num() const { return _mNum; }
+
+ /**
+ * Returns the denominator of this range.
+ */
+ inline C2_HIDE constexpr T denom() const { return _mDenom; }
+
+private:
+ /**
+ * Returns whether x[i...] is all values between _mMin and _mMax.
+ */
+ inline C2_HIDE constexpr bool isSimpleRange() const {
+ return _mStep == MIN_STEP && _mNum == 1 && _mDenom == 1;
+ }
+
+ /**
+ * Returns whether x[i...] is defined as such:
+ * x[i + 1] = x[i] + _mStep, where _mStep > 0 and _mMin <= x[i] <= _mMax
+ */
+ inline C2_HIDE constexpr bool isArithmeticSeries() const {
+ return _mStep > MIN_STEP && _mNum == 1 && _mDenom == 1;
+ }
+
+ /**
+ * Returns whether x[i...] is defined as such:
+ * x[i] = x[0] * (_mNum / _mDenom) ^ i (with rounding), where _mNum > _mDenom > 0 and x[0] > 0
+ */
+ inline C2_HIDE constexpr bool isGeometricSeries() const {
+ return _mMin > 0 && _mStep == 0 && _mNum > _mDenom && _mDenom > 0;
+ }
+
+ /**
+ * Returns whether x[i...] is defined as such:
+ * x[i + 1] = x[i] * _mNum / _mDenom + _mStep (with rounding), while x[i + 1] > x[i], where
+ * _mStep != 0, _mDenom > 0 and _mNum > 0
+ */
+ inline C2_HIDE constexpr bool isMacSeries() const {
+ return _mStep != 0 && _mNum > 0 && _mDenom > 0;
+ }
+
+ /**
+ * Constructs an arithmetic or continuous range.
+ *
+ * \param min the lower value
+ * \param max the higher value (if this is lower than |min| the range will be empty)
+ * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
+ * integer types, the constructed range is continuous)
+ */
+ constexpr C2_HIDE C2SupportedRange(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
+ : _mMin(min), _mMax(max), _mStep(step), _mNum(1), _mDenom(1) { }
+
+ /**
+ * Constructs a range over a geomertic sor multiply-accumulate series.
+ *
+ * \param min the lower bound of the range. This value is always part of the constructed range
+ * as long as it is not greater than |max|.
+ * \param max the upper bound of the range. This value is only part of the constructed
+ * range if it is part of the geometric series.
+ * \param step the accumulator of the multiply-accumulate series. This is 0 for a pure geometric
+ * series
+ * \param num the numerator of the geometric series.
+ * \param denom the denominator of the geometric series.
+ */
+ constexpr C2_HIDE C2SupportedRange(T min, T max, T step, T num, T den)
+ : _mMin(min), _mMax(max), _mStep(step), _mNum(num), _mDenom(den) { }
+
+ T _mMin; ///< lower bound and starting point
+ T _mMax; ///< upper bound
+ T _mStep; ///< step of an arithmetic series (0 if continuous floating point range)
+ T _mNum; ///< numerator of a geometric series
+ T _mDenom; ///< denominator of a geometric series
+};
+
+/**
+ * Ordered supported flag set for a field of a given type.
+ */
+template<typename T>
+class C2SupportedFlags {
+ typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+public:
+ /**
+ * Constructs an empty flag set.
+ *
+ * \note This is a specializated supported flags representation that is only used for
+ * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+ */
+ static inline C2SupportedFlags<T> None() {
+ return C2SupportedFlags(std::initializer_list<C2Value::Primitive>());
+ }
+
+ /**
+ * Constructs a flags set of given flags.
+ *
+ * \param flags the ordered set of flags as an initializer list.
+ * \param min minimum set of flags to be set.
+ */
+ static inline C2SupportedFlags<T> Flags(const std::initializer_list<T> flags, T min = T(0)) {
+ return C2SupportedFlags(min, flags);
+ }
+
+ /**
+ * Constructs a flags set of given flags.
+ *
+ * \param flags the ordered set of flags.
+ * \param min minimum set of flags to be set.
+ */
+ static inline C2SupportedFlags<T> Flags(const std::vector<T> &flags, T min = T(0)) {
+ return C2SupportedFlags(min, flags);
+ }
+
+ /**
+ * Constructs a flag set from a generic C2FieldSupportedValues object. This will be an empty
+ * set if the supported values are not of FLAGS type.
+ *
+ * \param values the supported values object
+ */
+ C2SupportedFlags<T>(const C2FieldSupportedValues &values) {
+ if (values.type == C2FieldSupportedValues::FLAGS) {
+ _mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
+ }
+ }
+
+ /**
+ * Returns whether this set is empty.
+ */
+ constexpr bool isEmpty() const {
+ return _mValues.empty();
+ }
+
+ /**
+ * Returns whether a value is part of this set.
+ *
+ * \param value the value to check.
+ */
+ bool contains(T value) const;
+
+ /**
+ * Returns a new flag set that is the intersection of this set and another.
+ *
+ * \param limit the other value set
+ */
+ C2SupportedFlags<T> limitedTo(const C2SupportedFlags<T> &limit) const;
+
+ /**
+ * Converts this object to a C2FieldSupportedValues object.
+ */
+ operator C2FieldSupportedValues() const {
+ return C2FieldSupportedValues(!isEmpty() /* flags */, _mValues);
+ }
+
+ /**
+ * Returns the ordered set of flags of this object.
+ */
+ const std::vector<T> flags() const;
+
+ /**
+ * Returns the minimum set of flags for this object.
+ */
+ T min() const;
+
+ /**
+ * Clears this supported value set.
+ */
+ inline void clear() {
+ _mValues.clear();
+ }
+
+private:
+ /**
+ * Constructs a flag set directly from an internal representation.
+ *
+ * \param values a vector containing the minimum flag set followed by the set of flags
+ */
+ C2SupportedFlags(std::vector<C2Value::Primitive> &&values)
+ : _mValues(values) {
+ }
+
+ /**
+ * Constructs a flag set from a set of flags and a minimum flag set.
+ *
+ * \param flags the set
+ */
+ C2SupportedFlags(T min, const std::vector<T> &flags) {
+ _mValues.emplace_back(min);
+ for (T elem : flags) {
+ _mValues.emplace_back(elem);
+ }
+ }
+
+ /**
+ * Constructs a flag set from a set of initializer list values and a minimum flag set
+ *
+ * \param flags the set
+ */
+ C2SupportedFlags(T min, const std::initializer_list<T> flags) {
+ _mValues.emplace_back(min);
+ for (T elem : flags) {
+ _mValues.emplace_back(elem);
+ }
+ }
+
+ std::vector<C2Value::Primitive> _mValues; ///< the minimum flag set followed by the set of flags
+};
+
+/**
+ * Ordered supported value set for a field of a given type.
+ */
+template<typename T>
+class C2SupportedValueSet {
+ typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
+
+public:
+ /**
+ * Constructs an empty value set.
+ *
+ * \note This is a specializated supported range representation that is only used for
+ * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
+ */
+ static inline C2SupportedValueSet<T> None() {
+ return C2SupportedValueSet({ });
+ }
+
+ /**
+ * Constructs a value set of given values.
+ *
+ * \param values the ordered set of values as an initializer list.
+ */
+ static inline C2SupportedValueSet<T> OneOf(const std::initializer_list<T> values) {
+ return C2SupportedValueSet(values);
+ }
+
+ /**
+ * Constructs a value set of given values.
+ *
+ * \param values the ordered set of values.
+ */
+ static inline C2SupportedValueSet<T> OneOf(const std::vector<T> &values) {
+ return C2SupportedValueSet(values);
+ }
+
+ /**
+ * Constructs a value set from a generic C2FieldSupportedValues object. This will be an empty
+ * set if the supported values are not of VALUES type.
+ *
+ * \param values the supported values object
+ */
+ C2SupportedValueSet<T>(const C2FieldSupportedValues &values) {
+ if (values.type == C2FieldSupportedValues::VALUES) {
+ _mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
+ }
+ }
+
+ /**
+ * Returns whether this range is empty.
+ */
+ constexpr bool isEmpty() const {
+ return _mValues.empty();
+ }
+
+ /**
+ * Returns whether a value is part of this set.
+ *
+ * \param value the value to check.
+ */
+ bool contains(T value) const;
+
+ /**
+ * Returns a new value set that is the intersection of this set and another.
+ *
+ * \param limit the other value set
+ */
+ C2SupportedValueSet<T> limitedTo(const C2SupportedValueSet<T> &limit) const;
+
+ /**
+ * Returns a new value set that is the intersection of this set and a value range.
+ *
+ * \param limit the other range
+ */
+ C2SupportedValueSet<T> limitedTo(const C2SupportedRange<T> &limit) const;
+
+ /**
+ * Returns a new value set that is the intersection of this set and a flag set.
+ *
+ * \param limit the other flag set
+ */
+ C2SupportedValueSet<T> limitedTo(const C2SupportedFlags<T> &limit) const;
+
+ /**
+ * Converts this object to a C2FieldSupportedValues object.
+ */
+ operator C2FieldSupportedValues() const {
+ return C2FieldSupportedValues(false /* flags */, _mValues);
+ }
+
+ /**
+ * Returns the ordered set of values of this object.
+ */
+ const std::vector<T> values() const;
+
+ /**
+ * Clears this supported value set.
+ */
+ inline void clear() {
+ _mValues.clear();
+ }
+
+private:
+ /**
+ * Constructs a value set from a set of C2Value::Primitive values.
+ *
+ * \param values the set
+ */
+ C2SupportedValueSet(std::vector<C2Value::Primitive> &&values)
+ : _mValues(values) {
+ }
+
+ /**
+ * Constructs a value set from a set of values.
+ *
+ * \param values the set
+ */
+ C2SupportedValueSet(const std::vector<T> &values) {
+ for (T elem : values) {
+ _mValues.emplace_back(elem);
+ }
+ }
+
+ /**
+ * Constructs a value set from a set of initializer list values
+ *
+ * \param values the set
+ */
+ C2SupportedValueSet(const std::initializer_list<T> values) {
+ for (T elem : values) {
+ _mValues.emplace_back(elem);
+ }
+ }
+
+ std::vector<C2Value::Primitive> _mValues; ///< the supported set of values
+};
+
+/**
+ * Helper class to handle C2FieldSupporteValues object for fields of various types.
+ */
+template<typename T>
+class C2FieldSupportedValuesHelper;
+
+// templated operator must be predeclared for friend declaration
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+
+template<typename T>
+class C2FieldSupportedValuesHelper {
+public:
+ /**
+ * Creates a helper for a specific type from a generic C2FieldSupportedValues struct.
+ */
+ C2FieldSupportedValuesHelper(const C2FieldSupportedValues &values);
+
+ // TRICKY: needed for std::unique_ptr<Impl> declaration
+ ~C2FieldSupportedValuesHelper();
+
+ // support copy constructor/operator
+ C2FieldSupportedValuesHelper(const C2FieldSupportedValuesHelper &);
+ C2FieldSupportedValuesHelper& operator=(const C2FieldSupportedValuesHelper &);
+
+ bool supports(T value) const;
+
+private:
+ // use pimpl as implementation may change in the future
+ struct Impl;
+ std::unique_ptr<Impl> _mImpl;
+
+ friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
+ //friend std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper &i);
+};
+
+/**
+ * Builder for supported values for a field of a given type.
+ *
+ * This builder can be used to successively restrict the supported values for a field. Upon
+ * creation, there are no supported values specified - which for this builder means that all
+ * values are supported.
+ */
+template<typename T>
+class C2ParamFieldValuesBuilder {
+public:
+ /**
+ * Creates a builder with no defined values - but implicitly any value allowed.
+ */
+ C2ParamFieldValuesBuilder(const C2ParamField &field);
+
+ /**
+ * Get C2ParamFieldValues from this builder.
+ */
+ operator C2ParamFieldValues() const;
+
+ /**
+ * Define the supported values as the currently supported values of this builder.
+ */
+ C2ParamFieldValuesBuilder<T> &any();
+
+ /**
+ * Restrict (and thus define) the supported values to none.
+ *
+ * \note This really should not be used from the builder as all params must have supported
+ * values, but is here in case this is really the case.
+ */
+ C2ParamFieldValuesBuilder<T> &none();
+
+ /**
+ * Restrict (and thus define) the supported values to |value| alone.
+ */
+ C2ParamFieldValuesBuilder<T> &equalTo(T value);
+
+ /**
+ * Restrict (and thus define) the supported values to values greater than |value|.
+ */
+ inline C2ParamFieldValuesBuilder<T> &greaterThan(T value) {
+ return limitTo(C2SupportedRange<T>::GreaterThan(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values greater than or equal to |value|.
+ */
+ C2ParamFieldValuesBuilder<T> &greaterThanOrEqualTo(T value) {
+ return limitTo(C2SupportedRange<T>::GreaterThanOrEqualTo(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values greater than or equal to |value|.
+ */
+ C2ParamFieldValuesBuilder<T> ¬LessThan(T value) {
+ return limitTo(C2SupportedRange<T>::NotLessThan(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values less than or equal to |value|.
+ */
+ C2ParamFieldValuesBuilder<T> &lessThanOrEqualTo(T value) {
+ return limitTo(C2SupportedRange<T>::LessThanOrEqualTo(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values less than or equal to |value|.
+ */
+ C2ParamFieldValuesBuilder<T> ¬GreaterThan(T value) {
+ return limitTo(C2SupportedRange<T>::NotGreaterThan(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values less than |value|.
+ */
+ C2ParamFieldValuesBuilder<T> &lessThan(T value) {
+ return limitTo(C2SupportedRange<T>::LessThan(value));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values in the range of [ |min|, |max| ]
+ * with optional |step|.
+ */
+ C2ParamFieldValuesBuilder<T> &inRange(
+ T min, T max, T step = std::is_floating_point<T>::value ? T(0) : T(1)) {
+ return limitTo(C2SupportedRange<T>::InRange(min, max, step));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values in the geometric series starting
+ * from |min| with factor |num| / |denom|, not greater than |max|.
+ */
+ C2ParamFieldValuesBuilder<T> &inSeries(T min, T max, T num, T denom) {
+ return limitTo(C2SupportedRange<T>::InSeries(min, max, num, denom));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values in the multiply-accumulate series
+ * starting from |min| with factor |num| / |denom| and |step|, not greater than |max|.
+ */
+ C2ParamFieldValuesBuilder<T> &inMacSeries(T min, T max, T step, T num, T denom) {
+ return limitTo(C2SupportedRange<T>::InMacSeries(min, max, step, num, denom));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values in |values|.
+ */
+ C2ParamFieldValuesBuilder<T> &oneOf(const std::initializer_list<T> values) {
+ return limitTo(C2SupportedValueSet<T>::OneOf(values));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to values in |values|.
+ */
+ C2ParamFieldValuesBuilder<T> &oneOf(const std::vector<T> &values) {
+ return limitTo(C2SupportedValueSet<T>::OneOf(values));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to flags in |flags| with at least |min|
+ * set.
+ */
+ C2ParamFieldValuesBuilder<T> &flags(const std::vector<T> &flags, T min = T(0)) {
+ return limitTo(C2SupportedFlags<T>::Flags(flags, min));
+ }
+
+ /**
+ * Restrict (and thus define) the supported values to flags in |values| with at least |min|
+ * set.
+ */
+ C2ParamFieldValuesBuilder<T> &flags(const std::initializer_list<T> flags, T min = T(0)) {
+ return limitTo(C2SupportedFlags<T>::Flags(flags, min));
+ }
+
+ virtual ~C2ParamFieldValuesBuilder();
+
+ // support copy constructor/operator
+ C2ParamFieldValuesBuilder(const C2ParamFieldValuesBuilder &);
+ C2ParamFieldValuesBuilder& operator=(const C2ParamFieldValuesBuilder &);
+
+private:
+ /**
+ * Restrict (and thus define) the supported values to a value set.
+ */
+ C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedValueSet<T> &limit);
+
+ /**
+ * Restrict (and thus define) the supported values to a value set.
+ */
+ C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedFlags<T> &limit);
+
+ /**
+ * Restrict (and thus define) the supported values to a range.
+ */
+ C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedRange<T> &limit);
+
+ struct Impl;
+ std::unique_ptr<Impl> _mImpl;
+};
+
+/**
+ * Builder for a list of setting conflicts.
+ */
+class C2SettingConflictsBuilder {
+public:
+ /**
+ * Creates an empty list of setting conflicts.
+ */
+ C2SettingConflictsBuilder();
+
+ /**
+ * Creates a list containing a single setting conflict.
+ */
+ C2SettingConflictsBuilder(C2ParamFieldValues &&conflict);
+
+ /**
+ * Adds a conflict to the current list of conflicts and returns this
+ */
+ C2SettingConflictsBuilder& with(C2ParamFieldValues &&conflict);
+
+ /**
+ * Gets the current list of conflicts (and moves them out of this builder.)
+ * (this is why it is not const)
+ */
+ std::vector<C2ParamFieldValues> retrieveConflicts();
+
+ /**
+ * Returns whether the current list is empty.
+ */
+ inline bool empty() const { return _mConflicts.empty(); }
+
+ inline operator bool() const { return empty(); }
+
+private:
+ std::vector<C2ParamFieldValues> _mConflicts;
+};
+
+/**
+ * Setting result builder for a parameter.
+ */
+struct C2SettingResultBuilder {
+ /**
+ * Creates a read-only setting result failure.
+ *
+ * This does not take FSV as only the current value of the field is supported.
+ */
+ static C2SettingResult ReadOnly(const C2ParamField ¶m);
+
+ /**
+ * Creates a bad-value or infoinformational bad-value setting result failure.
+ *
+ * This does not take FSV as the value is outside of the possible values. As such, there are no
+ * conflicts for this case either.
+ */
+ static C2SettingResult BadValue(const C2ParamField ¶mField, bool isInfo = false);
+
+ /**
+ * Creates a conflict (or informational conflict) setting result failure.
+ *
+ * This takes FSV so use paramFieldValues and optional conflicts.
+ */
+ static C2SettingResult Conflict(
+ C2ParamFieldValues &¶mFieldValues, C2SettingConflictsBuilder &conflicts,
+ bool isInfo = false);
+
+ // TODO: retrieve results
+
+
+private:
+ C2ParamField _mParamField;
+ C2SettingResult _mResult;
+
+ C2SettingResultBuilder(const C2SettingResultBuilder &) = delete;
+};
+
+/**
+ * Setting results (PLURAL) builder.
+ *
+ * Setting results contain a failure status along with a list of failing fields or params.
+ */
+struct C2SettingResultsBuilder {
+ C2SettingResultsBuilder(const C2SettingResultsBuilder&) = delete;
+ C2SettingResultsBuilder(C2SettingResultsBuilder&&) = default;
+ C2SettingResultsBuilder &operator=(C2SettingResultsBuilder&&) = default;
+
+ /** \returns (default) successful result with no details. */
+ inline static C2SettingResultsBuilder Ok() {
+ return C2SettingResultsBuilder(C2_OK);
+ }
+
+ /** \returns Interface is in bad state, with no further details. */
+ inline static C2SettingResultsBuilder BadState() {
+ return C2SettingResultsBuilder(C2_BAD_STATE);
+ }
+
+ /** \returns Interface connection timed out, with no further details. */
+ inline static C2SettingResultsBuilder TimedOut() {
+ return C2SettingResultsBuilder(C2_TIMED_OUT);
+ }
+
+ /** \returns Interface connection is corrupted, with no further details. */
+ inline static C2SettingResultsBuilder Corrupted() {
+ return C2SettingResultsBuilder(C2_CORRUPTED);
+ }
+
+ inline static C2SettingResultsBuilder NoMemory(C2Param::Index index_ __unused) {
+ // TODO: try to add failure result
+ return C2SettingResultsBuilder(C2_NO_MEMORY);
+ }
+
+ // TODO: this should not be a constructor
+ /** Creates a builder with a single bad value setting result. */
+ C2SettingResultsBuilder(C2SettingResult &&result);
+
+ /** Combines this results with other results. */
+ C2SettingResultsBuilder plus(C2SettingResultsBuilder&& results);
+
+ /** Retrieve (get and move out) failures and return the failure status. */
+ c2_status_t retrieveFailures(std::vector<std::unique_ptr<C2SettingResult>>* const failures);
+
+private:
+ /** Setting results based on a single status. This is used when actual setting could not be
+ * attempted to get a single C2SettingResult, or when a setting succeeded without
+ * 'complaints'. */
+ C2SettingResultsBuilder(c2_status_t status);
+ // status must be one of OK, BAD_STATE, TIMED_OUT, CORRUPTED or NO_MEMORY
+ // mainly: BLOCKING, BAD_INDEX, BAD_VALUE and NO_MEMORY requires a setting attempt, but
+ // NO_MEMORY may not allow us to create a results structure.
+
+ /**
+ * One of OK, BAD_INDEX, BAD_VALUE, BAD_STATE, NO_MEMORY, TIMED_OUT, BLOCKING or CORRUPTED.
+ */
+ c2_status_t _mStatus __unused;
+
+ /**
+ * Vector of individual setting result details.
+ */
+ std::vector<std::unique_ptr<C2SettingResult>> _mResults;
+};
+
+/**
+ * Utility class to enumerate fields of parameters.
+ */
+struct C2FieldUtils {
+ struct _Inspector;
+
+ /**
+ * An extended field descriptor object with structural information (lineage back to the root of
+ * the param).
+ */
+ struct Info {
+ typedef C2FieldDescriptor::type_t type_t; ///< field type
+ typedef C2FieldDescriptor::NamedValuesType NamedValuesType; ///< named values list type
+
+ /// returns the name of the field
+ C2String name() const;
+
+ /// returns the type of this field
+ type_t type() const;
+
+ /**
+ * Returns the defined name-value pairings for this field. The returned reference is
+ * only valid during the validity of this object
+ */
+ const NamedValuesType &namedValues() const;
+
+ /**
+ * The index of this field. E.g. param.field or param.field[0] has an index of 0, and
+ * param.struct[2].field[3] has an index of 3.
+ */
+ size_t index() const;
+
+ /// returns the length of the field in case it is an array. Returns 0 for
+ /// T[] arrays if this info comes from a C2Param::Index object, and the currently used
+ /// extent if it comes from a C2Param object. Returns 1 for T[1] arrays as well as if the
+ /// field is not an array.
+ size_t extent() const;
+
+ /**
+ * The (structural) depth of this field. E.g. param.field or param.field[0] has a depth of
+ * 0, and param.struct.field or param.struct[0].field[0] has a depth of 1.
+ */
+ size_t depth() const;
+
+ /**
+ * Returns the offset of this field in the parameter in bytes.
+ */
+ size_t offset() const;
+
+ /**
+ * Returns the size of this field in bytes.
+ */
+ size_t size() const;
+
+ /**
+ * The offset of this field's array. E.g. for param.struct[2].field[3] this is the offset
+ * of its smallest sibling: param.struct[2].field[0].
+ */
+ size_t arrayOffset() const;
+
+ /**
+ * Returns the size of this field's array. This is equivalent to extent() * size()
+ */
+ size_t arraySize() const;
+
+ /**
+ * The offset of the base field. The base field is a cousin of the current field where
+ * all indices are 0. E.g. the the base field for param.struct[2].field[3] is
+ * param.struct[0].field[0]. Base fields are used to specify supported values for
+ * all cousin fields.
+ */
+ size_t baseFieldOffset() const;
+
+ /**
+ * Returns whether this field is an arithmetic (integral, counter or float) field.
+ */
+ bool isArithmetic() const;
+
+ /**
+ * Returns whether this field can have a flexible extent. extent() returns the current
+ * extent.
+ */
+ bool isFlexible() const;
+
+ /// returns whether this info is valid
+ inline bool isValid() const { return _mImpl != nullptr; }
+
+ /// returns the info for the parent of this field, or an invalid Info object if it has no
+ /// parents
+ Info parent() const;
+
+ /// returns whether this info is valid
+ inline operator bool() const { return isValid(); }
+
+ struct Impl;
+ Info(std::shared_ptr<Impl>);
+
+ private:
+ std::shared_ptr<Impl> _mImpl;
+ friend struct _Inspector;
+ };
+
+ /**
+ * An (input) iterator object over fields using Info objects.
+ */
+ struct Iterator {
+ typedef Info const value_type;
+ typedef ptrdiff_t difference_type;
+ typedef Info const * pointer;
+ typedef Info const reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ /// return Info at current position
+ virtual reference operator*() const;
+
+ /// move to the next field
+ virtual Iterator& operator++();
+
+ virtual bool operator==(const Iterator &) const;
+ inline bool operator!=(const Iterator &other) const { return !operator==(other); }
+
+ virtual ~Iterator() = default;
+
+ struct Impl;
+ Iterator(std::shared_ptr<Impl>);
+
+ protected:
+ std::shared_ptr<Impl> mImpl;
+ };
+
+ /**
+ * An (input) iterable object representing a list of fields.
+ */
+ struct List {
+ /// returns an iterator to the beginning of the list
+ virtual Iterator begin() const;
+
+ /// returns an iterator to the end of the list
+ virtual Iterator end() const;
+
+ virtual ~List() = default;
+
+ struct Impl;
+ List(std::shared_ptr<Impl>);
+
+ protected:
+ std::shared_ptr<Impl> mImpl;
+ };
+
+ /**
+ * Enumerates all (base) fields at index 0 of the parameter. The order of iteration is the
+ * following:
+ * Fields of a structure are enumerated in field order. However, sub-fields of a structure
+ * are enumerated directly after the structure field, and prior to sibling fields.
+ *
+ * In essence the order of enumeration is first by increasing offset, then by decreasing size.
+ *
+ * \param param parameter to enumerate its fields
+ * \param reflector parameter reflector used for enumeration
+ *
+ * \return an iterable object
+ */
+ static List enumerateFields(
+ const C2Param ¶m,
+ const std::shared_ptr<C2ParamReflector> &reflector);
+
+ /**
+ * Enumerates all cousin fields up to depth - level for a field. If level is 0, it enumerates
+ * only the field. For level 1, it enumerates all fields in its current array (which may be
+ * itself if extent is 1). The order of iteration is by increasing field offset.
+ */
+ static List enumerateCousins(
+ const Info &field,
+ uint32_t level = ~0);
+
+ /**
+ * Locates the field in a parameter and returns a list of 2 elements - the most-specific field
+ * array of the parameter that contains the entire field. If the field is not a valid field
+ * specifier for this parameter (e.g. it is outside the bounds of the parameter), it returns
+ * an empty list.
+ */
+ static std::vector<Info> locateField(
+ const C2Param ¶m, const _C2FieldId &field,
+ const std::shared_ptr<C2ParamReflector> &reflector);
+
+ static std::vector<Info> locateField(
+ const C2ParamField &pf, const std::shared_ptr<C2ParamReflector> &reflector);
+
+};
+
+#include <util/C2Debug-interface.h>
+
+#endif // C2UTILS_INTERFACE_UTILS_H_
diff --git a/media/codec2/vndk/include/util/C2ParamUtils.h b/media/codec2/vndk/include/util/C2ParamUtils.h
new file mode 100644
index 0000000..b51bd94
--- /dev/null
+++ b/media/codec2/vndk/include/util/C2ParamUtils.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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 C2UTILS_PARAM_UTILS_H_
+#define C2UTILS_PARAM_UTILS_H_
+
+#include <utility>
+#include <vector>
+
+/** \file
+ * Utilities for parameter handling to be used by Codec2 implementations.
+ */
+
+/// \cond INTERNAL
+
+struct C2Param;
+
+class C2ParamUtils {
+ friend class C2UtilTest_ParamUtilsTest_Test;
+
+public:
+
+ /// safe(r) parsing from parameter blob
+ static
+ C2Param *ParseFirst(const uint8_t *blob, size_t size);
+};
+
+/// \endcond
+
+#endif // C2UTILS_PARAM_UTILS_H_
+