diff options
author | Bartłomiej Grzesik <bgrzesik@google.com> | 2023-05-12 08:49:27 +0000 |
---|---|---|
committer | Bartłomiej Grzesik <bgrzesik@google.com> | 2023-05-25 11:38:31 +0000 |
commit | a72f5ccc348a1001da231e6ec6445e65ecc9503d (patch) | |
tree | 865dbc02def42b567eef9e19e2c1213c85c74a8f | |
parent | 8cc25005e47b590643e216b6fef8566920dfc3b3 (diff) | |
download | v4l2_codec2-a72f5ccc348a1001da231e6ec6445e65ecc9503d.tar.gz |
V4L2DecodeInterface: decouple interface from device
This CL is decoupling interface class from V4L2Device. This is
preparation work for upcoming VD backed implementation of VideoDecoder
for R-container.
Bug: 281818034
Bug: 267299128
Test: m
Change-Id: Iffa4a71c0bd7072427bbfc29abf310c8ec35f8a4
-rw-r--r-- | common/V4L2ComponentCommon.cpp | 35 | ||||
-rw-r--r-- | common/V4L2Device.cpp | 19 | ||||
-rw-r--r-- | common/include/v4l2_codec2/common/Common.h | 20 | ||||
-rw-r--r-- | common/include/v4l2_codec2/common/V4L2ComponentCommon.h | 9 | ||||
-rw-r--r-- | common/include/v4l2_codec2/common/V4L2Device.h | 14 | ||||
-rw-r--r-- | components/V4L2ComponentFactory.cpp | 40 | ||||
-rw-r--r-- | components/V4L2DecodeComponent.cpp | 13 | ||||
-rw-r--r-- | components/V4L2DecodeInterface.cpp | 39 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2ComponentFactory.h | 7 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2DecodeComponent.h | 5 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2DecodeInterface.h | 4 |
11 files changed, 141 insertions, 64 deletions
diff --git a/common/V4L2ComponentCommon.cpp b/common/V4L2ComponentCommon.cpp index f67a516..0e70b29 100644 --- a/common/V4L2ComponentCommon.cpp +++ b/common/V4L2ComponentCommon.cpp @@ -8,6 +8,7 @@ #include <v4l2_codec2/common/V4L2ComponentCommon.h> #include <log/log.h> +#include <set> namespace android { @@ -39,4 +40,38 @@ bool V4L2ComponentName::isEncoder(const char* name) { return name == kH264Encoder || name == kVP8Encoder || name == kVP9Encoder; } +// static +bool V4L2ComponentName::isDecoder(const std::string& name) { + ALOG_ASSERT(isValid(name)); + static const std::set<std::string> kValidDecoders = { + kH264Decoder, kH264SecureDecoder, kVP8Decoder, kVP8SecureDecoder, + kVP9Decoder, kVP9SecureDecoder, kHEVCDecoder, kHEVCSecureDecoder, + }; + + return kValidDecoders.find(name) != kValidDecoders.end(); +} + +// static +std::optional<VideoCodec> V4L2ComponentName::getCodec(const std::string& name) { + ALOG_ASSERT(isValid(name)); + static const std::map<std::string, VideoCodec> kNameToCodecs = { + {kH264Decoder, VideoCodec::H264}, {kH264SecureDecoder, VideoCodec::H264}, + {kH264Encoder, VideoCodec::H264}, + + {kVP8Decoder, VideoCodec::VP8}, {kVP8SecureDecoder, VideoCodec::VP8}, + {kVP8Encoder, VideoCodec::VP8}, + + {kVP9Decoder, VideoCodec::VP9}, {kVP9SecureDecoder, VideoCodec::VP9}, + {kVP9Encoder, VideoCodec::VP9}, + + {kHEVCDecoder, VideoCodec::HEVC}, {kHEVCSecureDecoder, VideoCodec::HEVC}, + }; + + auto iter = kNameToCodecs.find(name); + if (iter == kNameToCodecs.end()) { + return std::nullopt; + } + return iter->second; +} + } // namespace android diff --git a/common/V4L2Device.cpp b/common/V4L2Device.cpp index e5fa8a5..fc0ba22 100644 --- a/common/V4L2Device.cpp +++ b/common/V4L2Device.cpp @@ -2140,8 +2140,8 @@ std::vector<C2Config::level_t> V4L2Device::getSupportedDecodeLevels(VideoCodec v } // static -V4L2Device::SupportedProfiles V4L2Device::getSupportedProfiles( - V4L2Device::Type type, const std::vector<uint32_t>& pixelFormats) { +SupportedProfiles V4L2Device::getSupportedProfiles(V4L2Device::Type type, + const std::vector<uint32_t>& pixelFormats) { SupportedProfiles supportedProfiles; for (const auto& info : getDeviceInfosForType(type)) { @@ -2258,6 +2258,19 @@ C2Config::level_t V4L2Device::getDefaultLevel(VideoCodec codec) { return C2Config::LEVEL_UNUSED; } +// static +SupportedCapabilities V4L2Device::queryDecodingCapabilities(VideoCodec codec) { + SupportedCapabilities caps; + caps.codec = codec; + caps.supportedLevels = V4L2Device::getSupportedDecodeLevels(codec); + caps.defaultLevel = V4L2Device::getDefaultLevel(codec); + caps.supportedProfiles = V4L2Device::getSupportedProfiles( + V4L2Device::Type::kDecoder, {V4L2Device::videoCodecToPixFmt(codec)}); + caps.defaultLevel = V4L2Device::getDefaultLevel(codec); + + return caps; +} + std::vector<C2Config::level_t> V4L2Device::enumerateSupportedDecodeLevels( VideoCodec videoCodecType) { std::vector<C2Config::level_t> supportedLevels; @@ -2275,7 +2288,7 @@ std::vector<C2Config::level_t> V4L2Device::enumerateSupportedDecodeLevels( return supportedLevels; } -V4L2Device::SupportedProfiles V4L2Device::enumerateSupportedProfiles( +SupportedProfiles V4L2Device::enumerateSupportedProfiles( V4L2Device::Type type, const std::vector<uint32_t>& pixelFormats) { SupportedProfiles profiles; diff --git a/common/include/v4l2_codec2/common/Common.h b/common/include/v4l2_codec2/common/Common.h index 58c49c0..dfd9ca2 100644 --- a/common/include/v4l2_codec2/common/Common.h +++ b/common/include/v4l2_codec2/common/Common.h @@ -34,6 +34,26 @@ struct VideoFrameLayout { bool mMultiPlanar = false; }; +// Specification of an encoding profile supported by an encoder or decoder. +struct SupportedProfile { + C2Config::profile_t profile = C2Config::PROFILE_UNUSED; + ui::Size min_resolution; + ui::Size max_resolution; + uint32_t max_framerate_numerator = 0; + uint32_t max_framerate_denominator = 0; + bool encrypted_only = false; +}; +using SupportedProfiles = std::vector<SupportedProfile>; + +// Contains the capabilites of the decoder or encoder. +struct SupportedCapabilities { + VideoCodec codec; + SupportedProfiles supportedProfiles; + C2Config::profile_t defaultProfile = C2Config::PROFILE_UNUSED; + std::vector<C2Config::level_t> supportedLevels; + C2Config::level_t defaultLevel = C2Config::LEVEL_UNUSED; +}; + // Check whether |rect1| completely contains |rect2|. bool contains(const Rect& rect1, const Rect& rect2); diff --git a/common/include/v4l2_codec2/common/V4L2ComponentCommon.h b/common/include/v4l2_codec2/common/V4L2ComponentCommon.h index a5fbdaf..7e2ad8e 100644 --- a/common/include/v4l2_codec2/common/V4L2ComponentCommon.h +++ b/common/include/v4l2_codec2/common/V4L2ComponentCommon.h @@ -5,6 +5,8 @@ #ifndef ANDROID_V4L2_CODEC2_COMMON_V4L2_COMPONENT_COMMON_H #define ANDROID_V4L2_CODEC2_COMMON_V4L2_COMPONENT_COMMON_H +#include <v4l2_codec2/common/VideoTypes.h> +#include <optional> #include <string> namespace android { @@ -30,6 +32,13 @@ struct V4L2ComponentName { // Return true if |name| is a encoder name. // Note that |name| should be a valid component name. static bool isEncoder(const char* name); + + // Return true if |name| is a decoder name. + // Note that |name| should be a valid component name. + static bool isDecoder(const std::string& name); + + // Returns VideoCodec for |name| component + static std::optional<VideoCodec> getCodec(const std::string& name); }; } // namespace android diff --git a/common/include/v4l2_codec2/common/V4L2Device.h b/common/include/v4l2_codec2/common/V4L2Device.h index 7e7b941..67aaa61 100644 --- a/common/include/v4l2_codec2/common/V4L2Device.h +++ b/common/include/v4l2_codec2/common/V4L2Device.h @@ -341,17 +341,6 @@ private: class V4L2Device : public base::RefCountedThreadSafe<V4L2Device> { public: - // Specification of an encoding profile supported by an encoder. - struct SupportedProfile { - C2Config::profile_t profile = C2Config::PROFILE_UNUSED; - ui::Size min_resolution; - ui::Size max_resolution; - uint32_t max_framerate_numerator = 0; - uint32_t max_framerate_denominator = 0; - bool encrypted_only = false; - }; - using SupportedProfiles = std::vector<SupportedProfile>; - // Utility format conversion functions // If there is no corresponding single- or multi-planar format, returns 0. static uint32_t c2ProfileToV4L2PixFmt(C2Config::profile_t profile, bool sliceBased); @@ -406,6 +395,9 @@ public: // Gets first current profile for any device static C2Config::level_t getDefaultLevel(VideoCodec codec); + // Gets all capabilites of the decoder devices. + static SupportedCapabilities queryDecodingCapabilities(VideoCodec codec); + // Create and initialize an appropriate V4L2Device instance for the current platform, or return // nullptr if not available. static scoped_refptr<V4L2Device> create(uint32_t debugStreamId = -1); diff --git a/components/V4L2ComponentFactory.cpp b/components/V4L2ComponentFactory.cpp index a3f8837..ae62e38 100644 --- a/components/V4L2ComponentFactory.cpp +++ b/components/V4L2ComponentFactory.cpp @@ -10,7 +10,9 @@ #include <codec2/hidl/1.0/InputBufferManager.h> #include <log/log.h> +#include <v4l2_codec2/common/Common.h> #include <v4l2_codec2/common/V4L2ComponentCommon.h> +#include <v4l2_codec2/common/V4L2Device.h> #include <v4l2_codec2/components/V4L2DecodeComponent.h> #include <v4l2_codec2/components/V4L2DecodeInterface.h> #include <v4l2_codec2/components/V4L2EncodeComponent.h> @@ -71,7 +73,13 @@ c2_status_t V4L2ComponentFactory::createComponent(c2_node_id_t id, if (mIsEncoder) { *component = V4L2EncodeComponent::create(mComponentName, id, mReflector, deleter); } else { - *component = V4L2DecodeComponent::create(mComponentName, id, mReflector, deleter); + std::shared_ptr<V4L2DecodeInterface> intfImpl; + c2_status_t status = createDecodeInterface(&intfImpl); + if (status != C2_OK) { + return status; + } + + *component = V4L2DecodeComponent::create(mComponentName, id, std::move(intfImpl), deleter); } return *component ? C2_OK : C2_NO_MEMORY; } @@ -94,13 +102,37 @@ c2_status_t V4L2ComponentFactory::createInterface( deleter); return C2_OK; } else { + std::shared_ptr<V4L2DecodeInterface> intfImpl; + c2_status_t status = createDecodeInterface(&intfImpl); + if (status != C2_OK) { + return status; + } + *interface = std::shared_ptr<C2ComponentInterface>( - new SimpleInterface<V4L2DecodeInterface>( - mComponentName.c_str(), id, - std::make_shared<V4L2DecodeInterface>(mComponentName, mReflector)), + new SimpleInterface<V4L2DecodeInterface>(mComponentName.c_str(), id, + std::move(intfImpl)), deleter); return C2_OK; } } +c2_status_t V4L2ComponentFactory::createDecodeInterface( + std::shared_ptr<V4L2DecodeInterface>* intfImpl) { + if (!mCapabilites) { + auto codec = V4L2ComponentName::getCodec(mComponentName); + if (!codec) { + return C2_CORRUPTED; + } + mCapabilites = std::make_unique<SupportedCapabilities>( + V4L2Device::queryDecodingCapabilities(*codec)); + } + + *intfImpl = std::make_shared<V4L2DecodeInterface>(mComponentName, mReflector, *mCapabilites); + if (*intfImpl == nullptr) { + return C2_NO_MEMORY; + } + + return (*intfImpl)->status(); +} + } // namespace android diff --git a/components/V4L2DecodeComponent.cpp b/components/V4L2DecodeComponent.cpp index 3d4e35b..64e4b9d 100644 --- a/components/V4L2DecodeComponent.cpp +++ b/components/V4L2DecodeComponent.cpp @@ -157,7 +157,7 @@ std::atomic<uint32_t> V4L2DecodeComponent::sNextDebugStreamId = 0; // static std::shared_ptr<C2Component> V4L2DecodeComponent::create( - const std::string& name, c2_node_id_t id, const std::shared_ptr<C2ReflectorHelper>& helper, + const std::string& name, c2_node_id_t id, std::shared_ptr<V4L2DecodeInterface> intfImpl, C2ComponentFactory::ComponentDeleter deleter) { static const int32_t kMaxConcurrentInstances = property_get_int32("ro.vendor.v4l2_codec2.decode_concurrent_instances", -1); @@ -172,21 +172,14 @@ std::shared_ptr<C2Component> V4L2DecodeComponent::create( sNextDebugStreamId.store(0, std::memory_order_relaxed); } - auto intfImpl = std::make_shared<V4L2DecodeInterface>(name, helper); - if (intfImpl->status() != C2_OK) { - ALOGE("Failed to initialize V4L2DecodeInterface."); - return nullptr; - } - uint32_t debugStreamId = sNextDebugStreamId.fetch_add(1, std::memory_order_relaxed); return std::shared_ptr<C2Component>( - new V4L2DecodeComponent(debugStreamId, name, id, helper, intfImpl), deleter); + new V4L2DecodeComponent(debugStreamId, name, id, std::move(intfImpl)), deleter); } V4L2DecodeComponent::V4L2DecodeComponent(uint32_t debugStreamId, const std::string& name, c2_node_id_t id, - const std::shared_ptr<C2ReflectorHelper>& helper, - const std::shared_ptr<V4L2DecodeInterface>& intfImpl) + std::shared_ptr<V4L2DecodeInterface> intfImpl) : mDebugStreamId(debugStreamId), mIntfImpl(intfImpl), mIntf(std::make_shared<SimpleInterface<V4L2DecodeInterface>>(name.c_str(), id, mIntfImpl)) { diff --git a/components/V4L2DecodeInterface.cpp b/components/V4L2DecodeInterface.cpp index 313c64e..213a41b 100644 --- a/components/V4L2DecodeInterface.cpp +++ b/components/V4L2DecodeInterface.cpp @@ -15,8 +15,6 @@ #include <v4l2_codec2/common/Common.h> #include <v4l2_codec2/common/V4L2ComponentCommon.h> -#include <v4l2_codec2/common/V4L2Device.h> -#include <v4l2_codec2/components/V4L2Decoder.h> #include <v4l2_codec2/plugin_store/V4L2AllocatorId.h> namespace android { @@ -29,20 +27,6 @@ constexpr size_t kInputBufferSizeFor1080p = 1024 * 1024; // 1MB // Input bitstream buffer size for up to 4k streams. constexpr size_t kInputBufferSizeFor4K = 4 * kInputBufferSizeFor1080p; -std::optional<VideoCodec> getCodecFromComponentName(const std::string& name) { - if (name == V4L2ComponentName::kH264Decoder || name == V4L2ComponentName::kH264SecureDecoder) - return VideoCodec::H264; - if (name == V4L2ComponentName::kVP8Decoder || name == V4L2ComponentName::kVP8SecureDecoder) - return VideoCodec::VP8; - if (name == V4L2ComponentName::kVP9Decoder || name == V4L2ComponentName::kVP9SecureDecoder) - return VideoCodec::VP9; - if (name == V4L2ComponentName::kHEVCDecoder || name == V4L2ComponentName::kHEVCSecureDecoder) - return VideoCodec::HEVC; - - ALOGE("Unknown name: %s", name.c_str()); - return std::nullopt; -} - size_t calculateInputBufferSize(size_t area) { if (area > k4KArea) { ALOGW("Input buffer size for video size (%zu) larger than 4K (%zu) might be too small.", @@ -113,19 +97,13 @@ C2R V4L2DecodeInterface::MaxInputBufferSizeCalculator( } V4L2DecodeInterface::V4L2DecodeInterface(const std::string& name, - const std::shared_ptr<C2ReflectorHelper>& helper) - : C2InterfaceHelper(helper), mInitStatus(C2_OK) { + const std::shared_ptr<C2ReflectorHelper>& helper, + const SupportedCapabilities& caps) + : C2InterfaceHelper(helper), mInitStatus(C2_OK), mVideoCodec(caps.codec) { ALOGV("%s(%s)", __func__, name.c_str()); setDerivedInstance(this); - mVideoCodec = getCodecFromComponentName(name); - if (!mVideoCodec) { - ALOGE("Invalid component name: %s", name.c_str()); - mInitStatus = C2_BAD_VALUE; - return; - } - addParameter(DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND) .withConstValue(new C2ComponentKindSetting(C2Component::KIND_DECODER)) .build()); @@ -135,9 +113,7 @@ V4L2DecodeInterface::V4L2DecodeInterface(const std::string& name, ui::Size maxSize(1, 1); std::vector<uint32_t> profiles; - V4L2Device::SupportedProfiles supportedProfiles = V4L2Device::getSupportedProfiles( - V4L2Device::Type::kDecoder, {V4L2Device::videoCodecToPixFmt(*mVideoCodec)}); - for (const auto& supportedProfile : supportedProfiles) { + for (const auto& supportedProfile : caps.supportedProfiles) { if (isValidProfileForCodec(mVideoCodec.value(), supportedProfile.profile)) { profiles.push_back(static_cast<uint32_t>(supportedProfile.profile)); maxSize.setWidth(std::max(maxSize.width, supportedProfile.max_resolution.width)); @@ -171,13 +147,12 @@ V4L2DecodeInterface::V4L2DecodeInterface(const std::string& name, } } - uint32_t defaultProfile = V4L2Device::getDefaultProfile(*mVideoCodec); + uint32_t defaultProfile = caps.defaultProfile; if (defaultProfile == C2Config::PROFILE_UNUSED) defaultProfile = *std::min_element(profiles.begin(), profiles.end()); std::vector<unsigned int> levels; - std::vector<C2Config::level_t> supportedLevels = - V4L2Device::getSupportedDecodeLevels(*mVideoCodec); + std::vector<C2Config::level_t> supportedLevels = caps.supportedLevels; for (const auto& supportedLevel : supportedLevels) { levels.push_back(static_cast<unsigned int>(supportedLevel)); } @@ -213,7 +188,7 @@ V4L2DecodeInterface::V4L2DecodeInterface(const std::string& name, } } - uint32_t defaultLevel = V4L2Device::getDefaultLevel(*mVideoCodec); + uint32_t defaultLevel = caps.defaultLevel; if (defaultLevel == C2Config::LEVEL_UNUSED) defaultLevel = *std::min_element(levels.begin(), levels.end()); diff --git a/components/include/v4l2_codec2/components/V4L2ComponentFactory.h b/components/include/v4l2_codec2/components/V4L2ComponentFactory.h index fc6abea..5294e78 100644 --- a/components/include/v4l2_codec2/components/V4L2ComponentFactory.h +++ b/components/include/v4l2_codec2/components/V4L2ComponentFactory.h @@ -10,9 +10,13 @@ #include <C2ComponentFactory.h> #include <util/C2InterfaceHelper.h> +#include <v4l2_codec2/common/Common.h> namespace android { +struct SupportedCapabilities; +class V4L2DecodeInterface; + class V4L2ComponentFactory : public C2ComponentFactory { public: static std::unique_ptr<V4L2ComponentFactory> create( @@ -29,9 +33,12 @@ public: InterfaceDeleter deleter) override; private: + c2_status_t createDecodeInterface(std::shared_ptr<V4L2DecodeInterface>* intfImpl); + const std::string mComponentName; const bool mIsEncoder; std::shared_ptr<C2ReflectorHelper> mReflector; + std::unique_ptr<SupportedCapabilities> mCapabilites; }; } // namespace android diff --git a/components/include/v4l2_codec2/components/V4L2DecodeComponent.h b/components/include/v4l2_codec2/components/V4L2DecodeComponent.h index 8d189b5..bf880a8 100644 --- a/components/include/v4l2_codec2/components/V4L2DecodeComponent.h +++ b/components/include/v4l2_codec2/components/V4L2DecodeComponent.h @@ -27,11 +27,10 @@ class V4L2DecodeComponent : public C2Component, public std::enable_shared_from_this<V4L2DecodeComponent> { public: static std::shared_ptr<C2Component> create(const std::string& name, c2_node_id_t id, - const std::shared_ptr<C2ReflectorHelper>& helper, + std::shared_ptr<V4L2DecodeInterface> intfImpl, C2ComponentFactory::ComponentDeleter deleter); V4L2DecodeComponent(uint32_t debugStreamId, const std::string& name, c2_node_id_t id, - const std::shared_ptr<C2ReflectorHelper>& helper, - const std::shared_ptr<V4L2DecodeInterface>& intfImpl); + std::shared_ptr<V4L2DecodeInterface> intfImpl); ~V4L2DecodeComponent() override; // Implementation of C2Component. diff --git a/components/include/v4l2_codec2/components/V4L2DecodeInterface.h b/components/include/v4l2_codec2/components/V4L2DecodeInterface.h index 6cd2046..58761b1 100644 --- a/components/include/v4l2_codec2/components/V4L2DecodeInterface.h +++ b/components/include/v4l2_codec2/components/V4L2DecodeInterface.h @@ -12,13 +12,15 @@ #include <ui/Size.h> #include <util/C2InterfaceHelper.h> +#include <v4l2_codec2/common/Common.h> #include <v4l2_codec2/common/VideoTypes.h> namespace android { class V4L2DecodeInterface : public C2InterfaceHelper { public: - V4L2DecodeInterface(const std::string& name, const std::shared_ptr<C2ReflectorHelper>& helper); + V4L2DecodeInterface(const std::string& name, const std::shared_ptr<C2ReflectorHelper>& helper, + const SupportedCapabilities& caps); V4L2DecodeInterface(const V4L2DecodeInterface&) = delete; V4L2DecodeInterface& operator=(const V4L2DecodeInterface&) = delete; ~V4L2DecodeInterface() = default; |