media.c2 aidl: connect CCodec, Codec2Client and HAL
Test: m
Bug: 254050314
Change-Id: I63640f14416f8c3c3c4e1eb52ab85ae6bb04d421
diff --git a/media/codec2/vndk/C2Fence.cpp b/media/codec2/vndk/C2Fence.cpp
index 4c385f1..52ebe25 100644
--- a/media/codec2/vndk/C2Fence.cpp
+++ b/media/codec2/vndk/C2Fence.cpp
@@ -26,6 +26,8 @@
#include <C2FenceFactory.h>
#include <C2SurfaceSyncObj.h>
+#include <utility>
+
#define MAX_FENCE_FDS 1
class C2Fence::Impl {
@@ -485,17 +487,26 @@
mValid = (mPipeFd.get() >= 0);
}
+ PipeFenceImpl(::android::base::unique_fd &&ufd) : mPipeFd{std::move(ufd)} {
+ mValid = (mPipeFd.get() >= 0);
+ }
+
private:
friend struct _C2FenceFactory;
static constexpr int kPipeFenceWaitLimitSecs = 5;
mutable std::atomic<bool> mValid;
- ::android::base::unique_fd mPipeFd;
+ const ::android::base::unique_fd mPipeFd;
};
C2Fence _C2FenceFactory::CreatePipeFence(int fd) {
+ ::android::base::unique_fd ufd{fd};
+ return CreatePipeFence(std::move(ufd));
+}
+
+C2Fence _C2FenceFactory::CreatePipeFence(::android::base::unique_fd &&ufd) {
std::shared_ptr<_C2FenceFactory::PipeFenceImpl> impl =
- std::make_shared<_C2FenceFactory::PipeFenceImpl>(fd);
+ std::make_shared<_C2FenceFactory::PipeFenceImpl>(std::move(ufd));
std::shared_ptr<C2Fence::Impl> p = std::static_pointer_cast<C2Fence::Impl>(impl);
if (!p) {
ALOGE("PipeFence creation failure");
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 76c378d..e7fd14f 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -26,12 +26,15 @@
#include <C2BqBufferPriv.h>
#include <C2Component.h>
#include <C2Config.h>
+#include <C2IgbaBufferPriv.h>
#include <C2PlatformStorePluginLoader.h>
#include <C2PlatformSupport.h>
#include <codec2/common/HalSelection.h>
#include <cutils/properties.h>
#include <util/C2InterfaceHelper.h>
+#include <aidl/android/hardware/media/c2/IGraphicBufferAllocator.h>
+
#include <dlfcn.h>
#include <unistd.h> // getpagesize
@@ -92,6 +95,9 @@
/// returns a shared-singleton bufferqueue supporting gralloc allocator
std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
+ /// returns a shared-singleton IGBA supporting AHardwareBuffer/gralloc allocator
+ std::shared_ptr<C2Allocator> fetchIgbaAllocator();
+
/// component store to use
std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
// dependencies
@@ -158,6 +164,10 @@
*allocator = fetchBlobAllocator();
break;
+ case C2PlatformAllocatorStore::IGBA:
+ *allocator = fetchIgbaAllocator();
+ break;
+
default:
// Try to create allocator from platform store plugins.
c2_status_t res =
@@ -389,6 +399,18 @@
return allocator;
}
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIgbaAllocator() {
+ static std::mutex mutex;
+ static std::weak_ptr<C2Allocator> ahwbAllocator;
+ std::lock_guard<std::mutex> lock(mutex);
+ std::shared_ptr<C2Allocator> allocator = ahwbAllocator.lock();
+ if (allocator == nullptr) {
+ allocator = std::make_shared<C2AllocatorAhwb>(C2PlatformAllocatorStore::IGBA);
+ ahwbAllocator = allocator;
+ }
+ return allocator;
+}
+
namespace {
std::mutex gPreferredComponentStoreMutex;
std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
@@ -460,12 +482,13 @@
private:
c2_status_t _createBlockPool(
- C2PlatformAllocatorStore::id_t allocatorId,
+ C2PlatformAllocatorDesc &allocatorParam,
std::vector<std::shared_ptr<const C2Component>> components,
C2BlockPool::local_id_t poolId,
std::shared_ptr<C2BlockPool> *pool) {
std::shared_ptr<C2AllocatorStore> allocatorStore =
GetCodec2PlatformAllocatorStore();
+ C2PlatformAllocatorStore::id_t allocatorId = allocatorParam.allocatorId;
std::shared_ptr<C2Allocator> allocator;
c2_status_t res = C2_NOT_FOUND;
@@ -532,6 +555,22 @@
components.begin(), components.end());
}
break;
+ case C2PlatformAllocatorStore::IGBA:
+ res = allocatorStore->fetchAllocator(
+ C2PlatformAllocatorStore::IGBA, &allocator);
+ if (res == C2_OK) {
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2IgbaBlockPool(allocator,
+ allocatorParam.igba,
+ std::move(allocatorParam.waitableFd),
+ poolId), deleter);
+ *pool = ptr;
+ mBlockPools[poolId] = ptr;
+ mComponents[poolId].insert(
+ mComponents[poolId].end(),
+ components.begin(), components.end());
+ }
+ break;
default:
// Try to create block pool from platform store plugins.
std::shared_ptr<C2BlockPool> ptr;
@@ -554,10 +593,20 @@
C2PlatformAllocatorStore::id_t allocatorId,
std::vector<std::shared_ptr<const C2Component>> components,
std::shared_ptr<C2BlockPool> *pool) {
- std::unique_lock lock(mMutex);
- return _createBlockPool(allocatorId, components, mBlockPoolSeqId++, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return createBlockPool(allocator, components, pool);
}
+ c2_status_t createBlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ std::vector<std::shared_ptr<const C2Component>> components,
+ std::shared_ptr<C2BlockPool> *pool) {
+ std::unique_lock lock(mMutex);
+ return _createBlockPool(allocator, components, mBlockPoolSeqId++, pool);
+ }
+
+
c2_status_t getBlockPool(
C2BlockPool::local_id_t blockPoolId,
std::shared_ptr<const C2Component> component,
@@ -586,8 +635,10 @@
}
// TODO: remove this. this is temporary
if (blockPoolId == C2BlockPool::PLATFORM_START) {
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
return _createBlockPool(
- C2PlatformAllocatorStore::BUFFERQUEUE, {component}, blockPoolId, pool);
+ allocator, {component}, blockPoolId, pool);
}
return C2_NOT_FOUND;
}
@@ -644,7 +695,9 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- return sBlockPoolCache->createBlockPool(allocatorId, components, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return sBlockPoolCache->createBlockPool(allocator, components, pool);
}
c2_status_t CreateCodec2BlockPool(
@@ -653,7 +706,27 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- return sBlockPoolCache->createBlockPool(allocatorId, {component}, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return sBlockPoolCache->createBlockPool(allocator, {component}, pool);
+}
+
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ const std::vector<std::shared_ptr<const C2Component>> &components,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+
+ return sBlockPoolCache->createBlockPool(allocator, components, pool);
+}
+
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+
+ return sBlockPoolCache->createBlockPool(allocator, {component}, pool);
}
class C2PlatformComponentStore : public C2ComponentStore {
diff --git a/media/codec2/vndk/include/C2FenceFactory.h b/media/codec2/vndk/include/C2FenceFactory.h
index 9b09980..4f974ca 100644
--- a/media/codec2/vndk/include/C2FenceFactory.h
+++ b/media/codec2/vndk/include/C2FenceFactory.h
@@ -20,6 +20,8 @@
#include <C2Buffer.h>
+#include <android-base/unique_fd.h>
+
/*
* Create a list of fds from fence
*
@@ -69,6 +71,7 @@
/*
* Create C2Fence from an fd created by pipe()/pipe2() syscall.
+ * The ownership of \p fd is transterred to the returned C2Fence.
*
* \param fd An fd representing the write end from a pair of
* file descriptors which are created by
@@ -76,6 +79,15 @@
*/
static C2Fence CreatePipeFence(int fd);
+ /*
+ * Create C2Fence from a unique_fd created by pipe()/pipe2() syscall.
+ *
+ * \param ufd A unique_fd representing the write end from a pair
+ * of file descriptors which are created by
+ * pipe()/pipe2() syscall.
+ */
+ static C2Fence CreatePipeFence(::android::base::unique_fd &&ufd);
+
/**
* Create a native handle from fence for marshalling
*
diff --git a/media/codec2/vndk/include/C2IgbaBufferPriv.h b/media/codec2/vndk/include/C2IgbaBufferPriv.h
index a5676b7..5879263 100644
--- a/media/codec2/vndk/include/C2IgbaBufferPriv.h
+++ b/media/codec2/vndk/include/C2IgbaBufferPriv.h
@@ -17,6 +17,8 @@
#include <C2Buffer.h>
+#include <android-base/unique_fd.h>
+
#include <memory>
namespace aidl::android::hardware::media::c2 {
@@ -32,8 +34,9 @@
public:
explicit C2IgbaBlockPool(
const std::shared_ptr<C2Allocator> &allocator,
- const std::shared_ptr<
- ::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba,
+ const std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator>
+ &igba,
+ ::android::base::unique_fd &&ufd,
const local_id_t localId);
virtual ~C2IgbaBlockPool() = default;
@@ -89,8 +92,7 @@
C2IgbaBlockPoolData(
const AHardwareBuffer *buffer,
- const std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator>
- &igba);
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
virtual ~C2IgbaBlockPoolData() override;
@@ -103,7 +105,10 @@
void disown();
+ void registerIgba(std::shared_ptr<
+ ::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
+
bool mOwned;
const AHardwareBuffer *mBuffer;
- const std::weak_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> mIgba;
+ std::weak_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> mIgba;
};
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
index 221a799..6fa155a 100644
--- a/media/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -22,6 +22,12 @@
#include <memory>
+#include <android-base/unique_fd.h>
+
+namespace aidl::android::hardware::media::c2 {
+class IGraphicBufferAllocator;
+}
+
namespace android {
/**
@@ -164,6 +170,53 @@
std::shared_ptr<C2BlockPool> *pool);
/**
+ * BlockPool creation parameters regarding allocator.
+ *
+ * igba, waitableFd are required only when allocatorId is
+ * C2PlatformAllocatorStore::IGBA.
+ */
+struct C2PlatformAllocatorDesc {
+ C2PlatformAllocatorStore::id_t allocatorId;
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> igba;
+ ::android::base::unique_fd waitableFd; // This will be passed and moved to C2Fence
+ // implementation.
+};
+
+/**
+ * Creates a block pool.
+ * \param allocator allocator ID and parameters which are 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(
+ C2PlatformAllocatorDesc &allocator,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Creates a block pool.
+ * \param allocator allocator ID and parameters which are used to allocate blocks
+ * \param components the components using the block pool
+ * \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(
+ C2PlatformAllocatorDesc &allocator,
+ const std::vector<std::shared_ptr<const C2Component>> &components,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
* Returns the platform component store.
* \retval nullptr if the platform component store could not be obtained
*/
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
index 8198ee1..4baf2db 100644
--- a/media/codec2/vndk/internal/C2BlockInternal.h
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -39,6 +39,12 @@
}
+namespace aidl::android::hardware::media::c2 {
+
+// IGraphicBufferAllocator for media.c2 aidl
+class IGraphicBufferAllocator;
+}
+
typedef struct AHardwareBuffer AHardwareBuffer;
using bufferpool_BufferPoolData = android::hardware::media::bufferpool::BufferPoolData;
@@ -472,6 +478,16 @@
*/
static void DisownIgbaBlock(
const std::shared_ptr<_C2BlockPoolData>& poolData);
+
+ /**
+ * When the client receives a block from HAL, the client needs to store
+ * IGraphicBufferAllocator from which the block was originally allocated.
+ * The stored \p igba will be used in the dtor to deallocate the buffer.
+ * (calling IGraphicBufferAllocator::deallocate to reclaim.)
+ */
+ static void RegisterIgba(
+ const std::shared_ptr<_C2BlockPoolData>& poolData,
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
};
#endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
diff --git a/media/codec2/vndk/platform/C2IgbaBuffer.cpp b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
index 853d5a3..2051e8f 100644
--- a/media/codec2/vndk/platform/C2IgbaBuffer.cpp
+++ b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
@@ -67,7 +67,8 @@
return err;
}
std::shared_ptr<C2IgbaBlockPoolData> poolData =
- std::make_shared<C2IgbaBlockPoolData>(ahwb, igba);
+ std::make_shared<C2IgbaBlockPoolData>(
+ ahwb, const_cast<std::shared_ptr<C2IGBA>&>(igba));
*block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
return C2_OK;
} else {
@@ -79,7 +80,7 @@
C2IgbaBlockPoolData::C2IgbaBlockPoolData(
const AHardwareBuffer *buffer,
- const std::shared_ptr<C2IGBA> &igba) : mOwned(true), mBuffer(buffer), mIgba(igba) {
+ std::shared_ptr<C2IGBA> &igba) : mOwned(true), mBuffer(buffer), mIgba(igba) {
CHECK(mBuffer);
AHardwareBuffer_acquire(const_cast<AHardwareBuffer *>(mBuffer));
}
@@ -115,6 +116,10 @@
mOwned = false;
}
+void C2IgbaBlockPoolData::registerIgba(std::shared_ptr<C2IGBA> &igba) {
+ mIgba = igba;
+}
+
std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(AHardwareBuffer *ahwb) {
// TODO: get proper allocator? and synchronization? or allocator-less?
static std::shared_ptr<C2AllocatorAhwb> sAllocator = std::make_shared<C2AllocatorAhwb>(0);
@@ -148,22 +153,30 @@
}
}
+void _C2BlockFactory::RegisterIgba(
+ const std::shared_ptr<_C2BlockPoolData>& data,
+ std::shared_ptr<C2IGBA> &igba) {
+ if (data && data->getType() == _C2BlockPoolData::TYPE_AHWBUFFER) {
+ const std::shared_ptr<C2IgbaBlockPoolData> poolData =
+ std::static_pointer_cast<C2IgbaBlockPoolData>(data);
+ poolData->registerIgba(igba);
+ }
+}
+
C2IgbaBlockPool::C2IgbaBlockPool(
const std::shared_ptr<C2Allocator> &allocator,
const std::shared_ptr<C2IGBA> &igba,
+ ::android::base::unique_fd &&ufd,
const local_id_t localId) : mAllocator(allocator), mIgba(igba), mLocalId(localId) {
if (!mIgba) {
mValid = false;
return;
}
- // TODO: Remove IPC (This is a nested IPC call during c2aidl creatBlockPool().
- ::ndk::ScopedFileDescriptor fd;
- ::ndk::ScopedAStatus status = mIgba->getWaitableFd(&fd);
- if (!status.isOk()) {
+ if (ufd.get() < 0) {
mValid = false;
return;
}
- mWaitFence = _C2FenceFactory::CreatePipeFence(fd.release());
+ mWaitFence = _C2FenceFactory::CreatePipeFence(std::move(ufd));
if (!mWaitFence.valid()) {
mValid = false;
return;