diff options
author | Hirokazu Honda <hiroh@google.com> | 2018-05-09 22:25:19 +0800 |
---|---|---|
committer | Hirokazu Honda <hiroh@google.com> | 2018-07-31 23:06:27 +0900 |
commit | 3f3c8a483f27f2b2b4457bb823feba20c9011303 (patch) | |
tree | 7db00bc58ad41d2a5d036f4e0a088bf09d6f920f | |
parent | 585324eba42604f93b5ab50a662e0a340f135c3e (diff) | |
download | v4l2_codec2-3f3c8a483f27f2b2b4457bb823feba20c9011303.tar.gz |
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
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | C2VDAComponent.cpp | 89 | ||||
-rw-r--r-- | include/C2VDAComponent.h | 5 |
3 files changed, 75 insertions, 21 deletions
@@ -56,8 +56,8 @@ LOCAL_SRC_FILES += \ LOCAL_SRC_FILES := $(filter-out C2VDAAdaptor.cpp, $(LOCAL_SRC_FILES)) LOCAL_SHARED_LIBRARIES += libarcbridge \ libarcbridgeservice \ - libmojo \ libcodec2_arcva_factory \ + libmojo \ endif # ifneq (,$(findstring cheets_,$(TARGET_PRODUCT))) 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 C2BlockPool::local_id_t kDefaultOutputBlockPool = C2BlockPool::BASIC_GRAPH 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 @@ C2VDAComponent::IntfImpl::IntfImpl(C2String name, const std::shared_ptr<C2Reflec // 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 @@ C2VDAComponent::IntfImpl::IntfImpl(C2String name, const std::shared_ptr<C2Reflec .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 @@ C2VDAComponent::C2VDAComponent(C2String name, c2_node_id_t id, 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 @@ void C2VDAComponent::onStart(media::VideoCodecProfile profile, ::base::WaitableE 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 @@ c2_status_t C2VDAComponent::allocateBuffersFromBlockAllocator(const media::Size& 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 @@ c2_status_t C2VDAComponent::allocateBuffersFromBlockAllocator(const media::Size& 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 @@ void C2VDAComponent::appendOutputBuffer(std::shared_ptr<C2GraphicBlock> block, u 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 @@ void C2VDAComponent::dequeueThreadLoop(const media::Size& size, uint32_t pixelFo 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 @@ private: }; } // 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 @@ extern "C" void DestroyC2VDAH264Factory(::C2ComponentFactory* factory) { 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 @@ extern "C" void DestroyC2VDAVP8Factory(::C2ComponentFactory* factory) { 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) { diff --git a/include/C2VDAComponent.h b/include/C2VDAComponent.h index c348dac..cfd828d 100644 --- a/include/C2VDAComponent.h +++ b/include/C2VDAComponent.h @@ -215,6 +215,8 @@ private: c2_status_t allocateBuffersFromBlockAllocator(const media::Size& size, uint32_t pixelFormat); // Append allocated buffer (graphic block) to mGraphicBlocks. void appendOutputBuffer(std::shared_ptr<C2GraphicBlock> block, uint32_t poolId); + // Append allocated buffer (graphic block) to mGraphicBlocks in secure mode. + void appendSecureOutputBuffer(std::shared_ptr<C2GraphicBlock> block, uint32_t poolId); // Check for finished works in mPendingWorks. If any, make onWorkDone call to listener. void reportFinishedWorkIfAny(); @@ -293,6 +295,9 @@ private: // finished. int64_t mLastOutputTimestamp; + // The indicator of whether component is in secure mode. + bool mSecureMode; + // The following members should be utilized on parent thread. // The input codec profile which is configured in component interface. |