C2VDAComponent: Add secure components to enable ARC++ DRM L1 for Codec 2.0
Bug: 73870167
Test: Play secure videos with ExoPlayer.app
Change-Id: I72c9652932fa3cf200191f2a459142aaffd01956
diff --git a/C2VDAComponent.cpp b/C2VDAComponent.cpp
index 6839130..dd48d33 100644
--- a/C2VDAComponent.cpp
+++ b/C2VDAComponent.cpp
@@ -34,6 +34,7 @@
#include <inttypes.h>
#include <string.h>
#include <algorithm>
+#include <string>
#define UNUSED(expr) \
do { \
@@ -55,6 +56,9 @@
const C2String kH264DecoderName = "c2.vda.avc.decoder";
const C2String kVP8DecoderName = "c2.vda.vp8.decoder";
const C2String kVP9DecoderName = "c2.vda.vp9.decoder";
+const C2String kH264SecureDecoderName = "c2.vda.avc.decoder.secure";
+const C2String kVP8SecureDecoderName = "c2.vda.vp8.decoder.secure";
+const C2String kVP9SecureDecoderName = "c2.vda.vp9.decoder.secure";
const uint32_t kDpbOutputBufferExtraCount = 3; // Use the same number as ACodec.
const int kDequeueRetryDelayUs = 10000; // Wait time of dequeue buffer retry in microseconds.
@@ -67,13 +71,13 @@
// TODO(johnylin): use factory function to determine whether V4L2 stream or slice API is.
uint32_t inputFormatFourcc;
char inputMime[128];
- if (name == kH264DecoderName) {
+ if (name == kH264DecoderName || name == kH264SecureDecoderName) {
strcpy(inputMime, MEDIA_MIMETYPE_VIDEO_AVC);
inputFormatFourcc = V4L2_PIX_FMT_H264_SLICE;
- } else if (name == kVP8DecoderName) {
+ } else if (name == kVP8DecoderName || name == kVP8SecureDecoderName) {
strcpy(inputMime, MEDIA_MIMETYPE_VIDEO_VP8);
inputFormatFourcc = V4L2_PIX_FMT_VP8_FRAME;
- } else if (name == kVP9DecoderName) {
+ } else if (name == kVP9DecoderName || name == kVP9SecureDecoderName) {
strcpy(inputMime, MEDIA_MIMETYPE_VIDEO_VP9);
inputFormatFourcc = V4L2_PIX_FMT_VP9_FRAME;
} else {
@@ -139,8 +143,13 @@
.withSetter(LocalSetter::SizeSetter)
.build());
- C2Allocator::id_t inputAllocators[] = {C2PlatformAllocatorStore::ION};
- C2Allocator::id_t outputAllocators[] = {C2VDAAllocatorStore::V4L2_BUFFERPOOL};
+ bool secureMode = name.find(".secure") != std::string::npos;
+ C2Allocator::id_t inputAllocators[] = {secureMode ? C2VDAAllocatorStore::SECURE_LINEAR
+ : C2PlatformAllocatorStore::ION};
+ C2Allocator::id_t outputAllocators[] = {secureMode ? C2VDAAllocatorStore::SECURE_GRAPHIC
+ : C2VDAAllocatorStore::V4L2_BUFFERQUEUE};
+ // TODO: change as below after ag/4660016 is landed.
+ // C2Allocator::id_t outputAllocators[] = {C2VDAAllocatorStore::V4L2_BUFFERPOOL};
addParameter(
DefineParam(mInputAllocatorIds, C2_PARAMKEY_INPUT_ALLOCATORS)
@@ -201,6 +210,8 @@
ALOGE("Component interface init failed (err code = %d)", mIntfImpl->status());
return;
}
+
+ mSecureMode = name.find(".secure") != std::string::npos;
if (!mThread.Start()) {
ALOGE("Component thread failed to start.");
return;
@@ -240,9 +251,7 @@
mVDAAdaptor.reset(new C2VDAAdaptor());
#endif
- // TODO: Set secureMode value dynamically.
- bool secureMode = false;
- mVDAInitResult = mVDAAdaptor->initialize(profile, secureMode, this);
+ mVDAInitResult = mVDAAdaptor->initialize(profile, mSecureMode, this);
if (mVDAInitResult == VideoDecodeAcceleratorAdaptor::Result::SUCCESS) {
mComponentState = ComponentState::STARTED;
}
@@ -732,7 +741,8 @@
for (size_t i = 0; i < bufferCount; ++i) {
std::shared_ptr<C2GraphicBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, 0};
+ C2MemoryUsage usage = {
+ mSecureMode ? C2MemoryUsage::READ_PROTECTED : C2MemoryUsage::CPU_READ, 0};
err = blockPool->fetchGraphicBlock(size.width(), size.height(), pixelFormat, usage, &block);
if (err != C2_OK) {
mGraphicBlocks.clear();
@@ -752,7 +762,11 @@
reportError(err);
return err;
}
- appendOutputBuffer(std::move(block), poolId);
+ if (mSecureMode) {
+ appendSecureOutputBuffer(std::move(block), poolId);
+ } else {
+ appendOutputBuffer(std::move(block), poolId);
+ }
}
mOutputFormat.mMinNumBuffers = bufferCount;
@@ -831,6 +845,37 @@
mGraphicBlocks.push_back(std::move(info));
}
+void C2VDAComponent::appendSecureOutputBuffer(std::shared_ptr<C2GraphicBlock> block,
+ uint32_t poolId) {
+#ifdef V4L2_CODEC2_ARC
+ const C2Handle* const handle = block->handle();
+ const int handleFd = handle->data[0];
+ ::base::ScopedFD passedHandle(dup(handleFd));
+ if (!passedHandle.is_valid()) {
+ ALOGE("Failed to dup(%d), errno=%d", handleFd, errno);
+ reportError(C2_CORRUPTED);
+ return;
+ }
+
+ // TODO(hiroh): resolve pixel format here.
+ android::HalPixelFormat pixelFormat = pixelFormat == android::HalPixelFormat::NV12;
+ ALOGV("HAL pixel format: 0x%x", static_cast<uint32_t>(pixelFormat));
+
+ GraphicBlockInfo info;
+ info.mBlockId = static_cast<int32_t>(mGraphicBlocks.size());
+ info.mGraphicBlock = std::move(block);
+ info.mPoolId = poolId;
+ info.mHandle = std::move(passedHandle);
+ info.mPixelFormat = pixelFormat;
+ // In secure mode, since planes are not referred in Chrome side, empty plane is valid.
+ info.mPlanes.clear();
+ mGraphicBlocks.push_back(std::move(info));
+#else
+ ALOGE("appendSecureOutputBuffer() is not supported...");
+ reportError(C2_OMITTED);
+#endif // V4L2_CODEC2_ARC
+}
+
void C2VDAComponent::sendOutputBufferToAccelerator(GraphicBlockInfo* info) {
ALOGV("sendOutputBufferToAccelerator index=%d", info->mBlockId);
CHECK_EQ(info->mState, GraphicBlockInfo::State::OWNED_BY_COMPONENT);
@@ -1190,7 +1235,8 @@
continue;
}
std::shared_ptr<C2GraphicBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, 0};
+ C2MemoryUsage usage = {
+ mSecureMode ? C2MemoryUsage::READ_PROTECTED : C2MemoryUsage::CPU_READ, 0};
auto err = blockPool->fetchGraphicBlock(size.width(), size.height(), pixelFormat, usage,
&block);
if (err == C2_TIMED_OUT) {
@@ -1251,9 +1297,10 @@
};
} // namespace android
-extern "C" ::C2ComponentFactory* CreateC2VDAH264Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2VDAComponentFactory(android::kH264DecoderName);
+extern "C" ::C2ComponentFactory* CreateC2VDAH264Factory(bool secureMode) {
+ ALOGV("in %s (secureMode=%d)", __func__, secureMode);
+ return secureMode ? new ::android::C2VDAComponentFactory(android::kH264SecureDecoderName)
+ : new ::android::C2VDAComponentFactory(android::kH264DecoderName);
}
extern "C" void DestroyC2VDAH264Factory(::C2ComponentFactory* factory) {
@@ -1261,9 +1308,10 @@
delete factory;
}
-extern "C" ::C2ComponentFactory* CreateC2VDAVP8Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2VDAComponentFactory(android::kVP8DecoderName);
+extern "C" ::C2ComponentFactory* CreateC2VDAVP8Factory(bool secureMode) {
+ ALOGV("in %s (secureMode=%d)", __func__, secureMode);
+ return secureMode ? new ::android::C2VDAComponentFactory(android::kVP8SecureDecoderName)
+ : new ::android::C2VDAComponentFactory(android::kVP8DecoderName);
}
extern "C" void DestroyC2VDAVP8Factory(::C2ComponentFactory* factory) {
@@ -1271,9 +1319,10 @@
delete factory;
}
-extern "C" ::C2ComponentFactory* CreateC2VDAVP9Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2VDAComponentFactory(android::kVP9DecoderName);
+extern "C" ::C2ComponentFactory* CreateC2VDAVP9Factory(bool secureMode) {
+ ALOGV("in %s (secureMode=%d)", __func__, secureMode);
+ return secureMode ? new ::android::C2VDAComponentFactory(android::kVP9SecureDecoderName)
+ : new ::android::C2VDAComponentFactory(android::kVP9DecoderName);
}
extern "C" void DestroyC2VDAVP9Factory(::C2ComponentFactory* factory) {