media.c2 aidl: Implement IGBA/AHwB based blockpool
Implement IGBA/AHwB based BlockPool(C2IgbaBlockPool).
Also implement IGBA/AHwB based GraphicBlock transfer between HAL and the
client.
Test: m
Bug: 254050314
Change-Id: Ie27a36d071440d807adda00fe1fa9f78ec413834
diff --git a/media/codec2/hal/aidl/BufferTypes.cpp b/media/codec2/hal/aidl/BufferTypes.cpp
index 1cd3555..b1af579 100644
--- a/media/codec2/hal/aidl/BufferTypes.cpp
+++ b/media/codec2/hal/aidl/BufferTypes.cpp
@@ -54,8 +54,10 @@
using ::aidl::android::hardware::media::c2::utils::BufferPoolTypes;
using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
+using AidlHardwareBuffer = ::aidl::android::hardware::HardwareBuffer;
constexpr BaseBlock::Tag NATIVE_BLOCK = BaseBlock::nativeBlock;
+constexpr BaseBlock::Tag HWB_BLOCK = BaseBlock::hwbBlock;
constexpr BaseBlock::Tag POOLED_BLOCK = BaseBlock::pooledBlock;
// BaseBlock -> C2BaseBlock
@@ -97,6 +99,21 @@
}
return false;
}
+ case HWB_BLOCK: {
+ AHardwareBuffer *pBuf =
+ const_cast<AidlHardwareBuffer&>(
+ s.get<HWB_BLOCK>()).release();
+ d->graphic = _C2BlockFactory::CreateGraphicBlock(pBuf);
+ if (pBuf) {
+ AHardwareBuffer_release(pBuf);
+ }
+ if (d->graphic) {
+ d->type = ::android::C2BaseBlock::GRAPHIC;
+ return true;
+ }
+ LOG(ERROR) << "Improper ahwb in BaseBlock::hwbBlock.";
+ return false;
+ }
case POOLED_BLOCK: {
const BufferStatusMessage &bpMessage = s.get<POOLED_BLOCK>();
std::shared_ptr<ClientManager> bp = ClientManager::getInstance();
@@ -188,6 +205,13 @@
}
template<>
+void SetAHardwareBuffer(BaseBlock *block, AHardwareBuffer *ahwb) {
+ AHardwareBuffer_acquire(ahwb);
+ block->set<HWB_BLOCK>(AidlHardwareBuffer());
+ (block->get<HWB_BLOCK>()).reset(ahwb);
+}
+
+template<>
void SetPooledBlock<BufferPoolTypes>(
BaseBlock *baseBlock,
const typename BufferPoolTypes::BufferStatusMessage &pooledBlock) {
@@ -326,6 +350,28 @@
return ::android::objcpy(d, s);
}
+void ReturnOutputBlocksToClientIfNeeded(
+ const std::list<std::unique_ptr<C2Work>>& workList) {
+ for (const std::unique_ptr<C2Work>& work : workList) {
+ if (!work) {
+ continue;
+ }
+ for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+ if (worklet) {
+ for (const std::shared_ptr<C2Buffer>& buffer : worklet->output.buffers) {
+ if (buffer) {
+ for (const C2ConstGraphicBlock& block : buffer->data().graphicBlocks()) {
+ std::shared_ptr<_C2BlockPoolData> poolData =
+ _C2BlockFactory::GetGraphicBlockPoolData(block);
+ _C2BlockFactory::DisownIgbaBlock(poolData);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
} // namespace utils
} // namespace c2
} // namespace media
diff --git a/media/codec2/hal/aidl/Component.cpp b/media/codec2/hal/aidl/Component.cpp
index 9c21a5b..2e0859b 100644
--- a/media/codec2/hal/aidl/Component.cpp
+++ b/media/codec2/hal/aidl/Component.cpp
@@ -113,26 +113,22 @@
WorkBundle workBundle;
std::shared_ptr<Component> strongComponent = mComponent.lock();
- // TODO
- // beginTransferBufferQueueBlocks(c2workItems, true);
if (!ToAidl(&workBundle, c2workItems, strongComponent ?
&strongComponent->mBufferPoolSender : nullptr)) {
LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
<< "received corrupted work items.";
- // TODO
- // endTransferBufferQueueBlocks(c2workItems, false, true);
return;
}
ScopedAStatus transStatus = listener->onWorkDone(workBundle);
if (!transStatus.isOk()) {
LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
<< "transaction failed.";
- // TODO
- // endTransferBufferQueueBlocks(c2workItems, false, true);
return;
}
- // TODO
- // endTransferBufferQueueBlocks(c2workItems, true, true);
+ // If output blocks are originally owned by the client(not by HAL),
+ // return the ownership to the client. (Since the blocks are
+ // transferred to the client here.)
+ ReturnOutputBlocksToClientIfNeeded(c2workItems);
}
}
@@ -210,15 +206,15 @@
}
}
- // TODO
- // beginTransferBufferQueueBlocks(c2flushedWorks, true);
if (c2res == C2_OK) {
if (!ToAidl(flushedWorkBundle, c2flushedWorks, &mBufferPoolSender)) {
c2res = C2_CORRUPTED;
}
}
- // TODO
- // endTransferBufferQueueBlocks(c2flushedWorks, true, true);
+ // If output blocks are originally owned by the client(not by HAL),
+ // return the ownership to the client. (Since the blocks are
+ // transferred to the client here.)
+ ReturnOutputBlocksToClientIfNeeded(c2flushedWorks);
if (c2res == C2_OK) {
return ScopedAStatus::ok();
}
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h b/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h
index 470863c..87fb855 100644
--- a/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h
+++ b/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h
@@ -115,6 +115,12 @@
std::list<std::unique_ptr<C2Work>>* d,
const WorkBundle& s);
+// Return the ownership of output blocks to the client if it is originally
+// created from the client, after C2Work is returned to the client.
+// (e.g. C2BqPool / C2IgbaBlockPool)
+void ReturnOutputBlocksToClientIfNeeded(
+ const std::list<std::unique_ptr<C2Work>>& workList);
+
/**
* Converts a BufferPool status value to c2_status_t.
* \param BufferPool status