Codec2Utils: Add support for media.c2@1.1
mediaswcodec will now present
android.hardware.media.c2@1.1::IComponentStore.
Test: make cts -j123 && cts-tradefed run cts-dev -m \
CtsMediaTestCases --compatibility:module-arg \
CtsMediaTestCases:include-annotation:\
android.platform.test.annotations.RequiresDevice
Test: make vts -j123 && vts-tradefed run commandAndExit vts \
-m VtsHalMediaC2V1_0Host
Bug: 136316504
Change-Id: I5a78e4faf5961861a07d6ea6e95198cd0d49f0f2
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
index 89c1c4a..3c37990 100644
--- a/media/codec2/hidl/client/Android.bp
+++ b/media/codec2/hidl/client/Android.bp
@@ -9,10 +9,12 @@
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.media.bufferpool@2.0",
"android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
"libbase",
"libbinder",
"libcodec2",
"libcodec2_hidl_client@1.0",
+ "libcodec2_hidl_client@1.1",
"libcodec2_vndk",
"libcutils",
"libgui",
@@ -28,8 +30,11 @@
],
export_shared_lib_headers: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
"libcodec2",
"libcodec2_hidl_client@1.0",
+ "libcodec2_hidl_client@1.1",
"libcodec2_vndk",
],
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index c747190..199a99c 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -19,6 +19,29 @@
#include <android-base/logging.h>
#include <codec2/hidl/client.h>
+#include <C2Debug.h>
+#include <C2BufferPriv.h>
+#include <C2PlatformSupport.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.0/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+#include <android-base/properties.h>
+#include <bufferpool/ClientManager.h>
+#include <codec2/hidl/1.0/OutputBufferQueue.h>
+#include <codec2/hidl/1.0/types.h>
+#include <codec2/hidl/1.1/OutputBufferQueue.h>
+#include <codec2/hidl/1.1/types.h>
+
+#include <cutils/native_handle.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+#include <hidl/HidlSupport.h>
#include <deque>
#include <iterator>
@@ -30,25 +53,6 @@
#include <type_traits>
#include <vector>
-#include <android-base/properties.h>
-#include <bufferpool/ClientManager.h>
-#include <cutils/native_handle.h>
-#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
-#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
-#include <hidl/HidlSupport.h>
-
-#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
-#include <android/hardware/media/c2/1.0/IComponent.h>
-#include <android/hardware/media/c2/1.0/IComponentInterface.h>
-#include <android/hardware/media/c2/1.0/IComponentListener.h>
-#include <android/hardware/media/c2/1.0/IComponentStore.h>
-#include <android/hardware/media/c2/1.0/IConfigurable.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-
-#include <C2Debug.h>
-#include <C2BufferPriv.h>
-#include <C2PlatformSupport.h>
-
namespace android {
using ::android::hardware::hidl_vec;
@@ -56,8 +60,8 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::media::c2::V1_0;
-using namespace ::android::hardware::media::c2::V1_0::utils;
+using namespace ::android::hardware::media::c2::V1_1;
+using namespace ::android::hardware::media::c2::V1_1::utils;
using namespace ::android::hardware::media::bufferpool::V2_0;
using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
@@ -514,8 +518,24 @@
};
+// Codec2Client::Component::BufferPoolSender
+struct Codec2Client::Component::BufferPoolSender :
+ hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
+ BufferPoolSender()
+ : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
+ }
+};
+
+// Codec2Client::Component::OutputBufferQueue
+struct Codec2Client::Component::OutputBufferQueue :
+ hardware::media::c2::V1_1::utils::OutputBufferQueue {
+ OutputBufferQueue()
+ : hardware::media::c2::V1_1::utils::OutputBufferQueue() {
+ }
+};
+
// Codec2Client
-Codec2Client::Codec2Client(const sp<IComponentStore>& base,
+Codec2Client::Codec2Client(sp<Base> const& base,
size_t serviceIndex)
: Configurable{
[base]() -> sp<IConfigurable> {
@@ -526,7 +546,8 @@
nullptr;
}()
},
- mBase{base},
+ mBase1_0{base},
+ mBase1_1{Base1_1::castFrom(base)},
mServiceIndex{serviceIndex} {
Return<sp<IClientManager>> transResult = base->getPoolClientManager();
if (!transResult.isOk()) {
@@ -537,7 +558,15 @@
}
sp<Codec2Client::Base> const& Codec2Client::getBase() const {
- return mBase;
+ return mBase1_0;
+}
+
+sp<Codec2Client::Base1_0> const& Codec2Client::getBase1_0() const {
+ return mBase1_0;
+}
+
+sp<Codec2Client::Base1_1> const& Codec2Client::getBase1_1() const {
+ return mBase1_1;
}
std::string const& Codec2Client::getServiceName() const {
@@ -552,7 +581,8 @@
c2_status_t status;
sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
hidlListener->base = listener;
- Return<void> transStatus = mBase->createComponent(
+ Return<void> transStatus = mBase1_1 ?
+ mBase1_1->createComponent_1_1(
name,
hidlListener,
ClientManager::getInstance(),
@@ -565,6 +595,20 @@
}
*component = std::make_shared<Codec2Client::Component>(c);
hidlListener->component = *component;
+ }) :
+ mBase1_0->createComponent(
+ name,
+ hidlListener,
+ ClientManager::getInstance(),
+ [&status, component, hidlListener](
+ Status s,
+ const sp<hardware::media::c2::V1_0::IComponent>& c) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK) {
+ return;
+ }
+ *component = std::make_shared<Codec2Client::Component>(c);
+ hidlListener->component = *component;
});
if (!transStatus.isOk()) {
LOG(ERROR) << "createComponent(" << name.c_str()
@@ -587,7 +631,7 @@
<< status << ".";
}
- (*component)->mBufferPoolSender.setReceiver(mHostPoolManager);
+ (*component)->mBufferPoolSender->setReceiver(mHostPoolManager);
return status;
}
@@ -595,7 +639,7 @@
const C2String& name,
std::shared_ptr<Codec2Client::Interface>* const interface) {
c2_status_t status;
- Return<void> transStatus = mBase->createInterface(
+ Return<void> transStatus = mBase1_0->createInterface(
name,
[&status, interface](
Status s,
@@ -622,7 +666,7 @@
c2_status_t Codec2Client::createInputSurface(
std::shared_ptr<InputSurface>* const inputSurface) {
c2_status_t status;
- Return<void> transStatus = mBase->createInputSurface(
+ Return<void> transStatus = mBase1_0->createInputSurface(
[&status, inputSurface](
Status s,
const sp<IInputSurface>& i) {
@@ -650,7 +694,7 @@
bool* success) const {
std::vector<C2Component::Traits> traits;
std::string const& serviceName = getServiceName();
- Return<void> transStatus = mBase->listComponents(
+ Return<void> transStatus = mBase1_0->listComponents(
[&traits, &serviceName](Status s,
const hidl_vec<IComponentStore::ComponentTraits>& t) {
if (s != Status::OK) {
@@ -734,7 +778,7 @@
sp<Base> mBase;
};
- return std::make_shared<SimpleParamReflector>(mBase);
+ return std::make_shared<SimpleParamReflector>(mBase1_0);
};
std::vector<std::string> const& Codec2Client::GetServiceNames() {
@@ -1053,8 +1097,32 @@
nullptr;
}()
},
- mBase{base},
- mBufferPoolSender{nullptr} {
+ mBase1_0{base},
+ mBase1_1{Base1_1::castFrom(base)},
+ mBufferPoolSender{std::make_unique<BufferPoolSender>()},
+ mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
+}
+
+Codec2Client::Component::Component(const sp<Base1_1>& base)
+ : Configurable{
+ [base]() -> sp<IConfigurable> {
+ Return<sp<IComponentInterface>> transResult1 =
+ base->getInterface();
+ if (!transResult1.isOk()) {
+ return nullptr;
+ }
+ Return<sp<IConfigurable>> transResult2 =
+ static_cast<sp<IComponentInterface>>(transResult1)->
+ getConfigurable();
+ return transResult2.isOk() ?
+ static_cast<sp<IConfigurable>>(transResult2) :
+ nullptr;
+ }()
+ },
+ mBase1_0{base},
+ mBase1_1{base},
+ mBufferPoolSender{std::make_unique<BufferPoolSender>()},
+ mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
}
Codec2Client::Component::~Component() {
@@ -1065,7 +1133,7 @@
C2BlockPool::local_id_t* blockPoolId,
std::shared_ptr<Codec2Client::Configurable>* configurable) {
c2_status_t status;
- Return<void> transStatus = mBase->createBlockPool(
+ Return<void> transStatus = mBase1_0->createBlockPool(
static_cast<uint32_t>(id),
[&status, blockPoolId, configurable](
Status s,
@@ -1090,7 +1158,7 @@
c2_status_t Codec2Client::Component::destroyBlockPool(
C2BlockPool::local_id_t localId) {
- Return<Status> transResult = mBase->destroyBlockPool(
+ Return<Status> transResult = mBase1_0->destroyBlockPool(
static_cast<uint64_t>(localId));
if (!transResult.isOk()) {
LOG(ERROR) << "destroyBlockPool -- transaction failed.";
@@ -1102,17 +1170,17 @@
void Codec2Client::Component::handleOnWorkDone(
const std::list<std::unique_ptr<C2Work>> &workItems) {
// Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue.holdBufferQueueBlocks(workItems);
+ mOutputBufferQueue->holdBufferQueueBlocks(workItems);
}
c2_status_t Codec2Client::Component::queue(
std::list<std::unique_ptr<C2Work>>* const items) {
WorkBundle workBundle;
- if (!objcpy(&workBundle, *items, &mBufferPoolSender)) {
+ if (!objcpy(&workBundle, *items, mBufferPoolSender.get())) {
LOG(ERROR) << "queue -- bad input.";
return C2_TRANSACTION_FAILED;
}
- Return<Status> transStatus = mBase->queue(workBundle);
+ Return<Status> transStatus = mBase1_0->queue(workBundle);
if (!transStatus.isOk()) {
LOG(ERROR) << "queue -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1130,7 +1198,7 @@
std::list<std::unique_ptr<C2Work>>* const flushedWork) {
(void)mode; // Flush mode isn't supported in HIDL yet.
c2_status_t status;
- Return<void> transStatus = mBase->flush(
+ Return<void> transStatus = mBase1_0->flush(
[&status, flushedWork](
Status s, const WorkBundle& wb) {
status = static_cast<c2_status_t>(s);
@@ -1165,13 +1233,13 @@
}
// Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue.holdBufferQueueBlocks(*flushedWork);
+ mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
return status;
}
c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
- Return<Status> transStatus = mBase->drain(
+ Return<Status> transStatus = mBase1_0->drain(
mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
if (!transStatus.isOk()) {
LOG(ERROR) << "drain -- transaction failed.";
@@ -1186,7 +1254,7 @@
}
c2_status_t Codec2Client::Component::start() {
- Return<Status> transStatus = mBase->start();
+ Return<Status> transStatus = mBase1_0->start();
if (!transStatus.isOk()) {
LOG(ERROR) << "start -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1200,7 +1268,7 @@
}
c2_status_t Codec2Client::Component::stop() {
- Return<Status> transStatus = mBase->stop();
+ Return<Status> transStatus = mBase1_0->stop();
if (!transStatus.isOk()) {
LOG(ERROR) << "stop -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1214,7 +1282,7 @@
}
c2_status_t Codec2Client::Component::reset() {
- Return<Status> transStatus = mBase->reset();
+ Return<Status> transStatus = mBase1_0->reset();
if (!transStatus.isOk()) {
LOG(ERROR) << "reset -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1228,7 +1296,7 @@
}
c2_status_t Codec2Client::Component::release() {
- Return<Status> transStatus = mBase->release();
+ Return<Status> transStatus = mBase1_0->release();
if (!transStatus.isOk()) {
LOG(ERROR) << "release -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1241,6 +1309,29 @@
return status;
}
+c2_status_t Codec2Client::Component::configureVideoTunnel(
+ uint32_t avSyncHwId,
+ native_handle_t** sidebandHandle) {
+ *sidebandHandle = nullptr;
+ if (!mBase1_1) {
+ return C2_OMITTED;
+ }
+ c2_status_t status{};
+ Return<void> transStatus = mBase1_1->configureVideoTunnel(avSyncHwId,
+ [&status, sidebandHandle](
+ Status s, hardware::hidl_handle const& h) {
+ status = static_cast<c2_status_t>(s);
+ if (h.getNativeHandle()) {
+ *sidebandHandle = native_handle_clone(h.getNativeHandle());
+ }
+ });
+ if (!transStatus.isOk()) {
+ LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+}
+
c2_status_t Codec2Client::Component::setOutputSurface(
C2BlockPool::local_id_t blockPoolId,
const sp<IGraphicBufferProducer>& surface,
@@ -1256,18 +1347,18 @@
}
if (!surface) {
- mOutputBufferQueue.configure(nullIgbp, generation, 0);
+ mOutputBufferQueue->configure(nullIgbp, generation, 0);
} else if (surface->getUniqueId(&bqId) != OK) {
LOG(ERROR) << "setOutputSurface -- "
"cannot obtain bufferqueue id.";
bqId = 0;
- mOutputBufferQueue.configure(nullIgbp, generation, 0);
+ mOutputBufferQueue->configure(nullIgbp, generation, 0);
} else {
- mOutputBufferQueue.configure(surface, generation, bqId);
+ mOutputBufferQueue->configure(surface, generation, bqId);
}
ALOGD("generation remote change %u", generation);
- Return<Status> transStatus = mBase->setOutputSurface(
+ Return<Status> transStatus = mBase1_0->setOutputSurface(
static_cast<uint64_t>(blockPoolId),
bqId == 0 ? nullHgbp : igbp);
if (!transStatus.isOk()) {
@@ -1286,14 +1377,14 @@
const C2ConstGraphicBlock& block,
const QueueBufferInput& input,
QueueBufferOutput* output) {
- return mOutputBufferQueue.outputBuffer(block, input, output);
+ return mOutputBufferQueue->outputBuffer(block, input, output);
}
c2_status_t Codec2Client::Component::connectToInputSurface(
const std::shared_ptr<InputSurface>& inputSurface,
std::shared_ptr<InputSurfaceConnection>* connection) {
c2_status_t status;
- Return<void> transStatus = mBase->connectToInputSurface(
+ Return<void> transStatus = mBase1_0->connectToInputSurface(
inputSurface->mBase,
[&status, connection](
Status s, const sp<IInputSurfaceConnection>& c) {
@@ -1317,7 +1408,7 @@
const sp<HGraphicBufferSource>& source,
std::shared_ptr<InputSurfaceConnection>* connection) {
c2_status_t status;
- Return<void> transStatus = mBase->connectToOmxInputSurface(
+ Return<void> transStatus = mBase1_0->connectToOmxInputSurface(
producer, source,
[&status, connection](
Status s, const sp<IInputSurfaceConnection>& c) {
@@ -1337,7 +1428,7 @@
}
c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
- Return<Status> transStatus = mBase->disconnectFromInputSurface();
+ Return<Status> transStatus = mBase1_0->disconnectFromInputSurface();
if (!transStatus.isOk()) {
LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1376,7 +1467,7 @@
deathRecipient->component = component;
component->mDeathRecipient = deathRecipient;
- Return<bool> transResult = component->mBase->linkToDeath(
+ Return<bool> transResult = component->mBase1_0->linkToDeath(
component->mDeathRecipient, 0);
if (!transResult.isOk()) {
LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index dca28f7..649dffd 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -17,14 +17,13 @@
#ifndef CODEC2_HIDL_CLIENT_H
#define CODEC2_HIDL_CLIENT_H
-#include <gui/IGraphicBufferProducer.h>
-#include <codec2/hidl/1.0/OutputBufferQueue.h>
#include <C2PlatformSupport.h>
#include <C2Component.h>
#include <C2Buffer.h>
#include <C2Param.h>
#include <C2.h>
+#include <gui/IGraphicBufferProducer.h>
#include <hidl/HidlSupport.h>
#include <utils/StrongPointer.h>
@@ -74,6 +73,11 @@
struct IInputSurfaceConnection;
} // namespace android::hardware::media::c2::V1_0
+namespace android::hardware::media::c2::V1_1 {
+struct IComponent;
+struct IComponentStore;
+} // namespace android::hardware::media::c2::V1_1
+
namespace android::hardware::media::bufferpool::V2_0 {
struct IClientManager;
} // namespace android::hardware::media::bufferpool::V2_0
@@ -82,6 +86,10 @@
struct IGraphicBufferProducer;
} // android::hardware::graphics::bufferqueue::V1_0
+namespace android::hardware::graphics::bufferqueue::V2_0 {
+struct IGraphicBufferProducer;
+} // android::hardware::graphics::bufferqueue::V2_0
+
namespace android::hardware::media::omx::V1_0 {
struct IGraphicBufferSource;
} // namespace android::hardware::media::omx::V1_0
@@ -127,7 +135,9 @@
struct Codec2Client : public Codec2ConfigurableClient {
- typedef ::android::hardware::media::c2::V1_0::IComponentStore Base;
+ typedef ::android::hardware::media::c2::V1_0::IComponentStore Base1_0;
+ typedef ::android::hardware::media::c2::V1_1::IComponentStore Base1_1;
+ typedef Base1_0 Base;
struct Listener;
@@ -144,6 +154,8 @@
typedef Codec2Client Store;
sp<Base> const& getBase() const;
+ sp<Base1_0> const& getBase1_0() const;
+ sp<Base1_1> const& getBase1_1() const;
std::string const& getServiceName() const;
@@ -206,7 +218,8 @@
Codec2Client(sp<Base> const& base, size_t serviceIndex);
protected:
- sp<Base> mBase;
+ sp<Base1_0> mBase1_0;
+ sp<Base1_1> mBase1_1;
// Finds the first store where the predicate returns C2_OK and returns the
// last predicate result. The predicate will be tried on all stores. The
@@ -295,7 +308,9 @@
struct Codec2Client::Component : public Codec2Client::Configurable {
- typedef ::android::hardware::media::c2::V1_0::IComponent Base;
+ typedef ::android::hardware::media::c2::V1_0::IComponent Base1_0;
+ typedef ::android::hardware::media::c2::V1_1::IComponent Base1_1;
+ typedef Base1_0 Base;
c2_status_t createBlockPool(
C2Allocator::id_t id,
@@ -322,6 +337,17 @@
c2_status_t release();
+ /**
+ * Use tunneling.
+ *
+ * On success, @p sidebandHandle will be a newly allocated native handle.
+ * File descriptors in @p sidebandHandle must be closed and
+ * @p sidebandHandle itself must be deleted afterwards.
+ */
+ c2_status_t configureVideoTunnel(
+ uint32_t avSyncHwId,
+ native_handle_t** sidebandHandle);
+
typedef ::android::
IGraphicBufferProducer IGraphicBufferProducer;
typedef IGraphicBufferProducer::
@@ -378,17 +404,19 @@
// base cannot be null.
Component(const sp<Base>& base);
+ Component(const sp<Base1_1>& base);
~Component();
protected:
- sp<Base> mBase;
+ sp<Base1_0> mBase1_0;
+ sp<Base1_1> mBase1_1;
- ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender
- mBufferPoolSender;
+ struct BufferPoolSender;
+ std::unique_ptr<BufferPoolSender> mBufferPoolSender;
- ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue
- mOutputBufferQueue;
+ struct OutputBufferQueue;
+ std::unique_ptr<OutputBufferQueue> mOutputBufferQueue;
static c2_status_t setDeathListener(
const std::shared_ptr<Component>& component,