aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartłomiej Grzesik <bgrzesik@google.com>2023-05-12 08:49:27 +0000
committerBartłomiej Grzesik <bgrzesik@google.com>2023-05-25 11:38:31 +0000
commita72f5ccc348a1001da231e6ec6445e65ecc9503d (patch)
tree865dbc02def42b567eef9e19e2c1213c85c74a8f
parent8cc25005e47b590643e216b6fef8566920dfc3b3 (diff)
downloadv4l2_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.cpp35
-rw-r--r--common/V4L2Device.cpp19
-rw-r--r--common/include/v4l2_codec2/common/Common.h20
-rw-r--r--common/include/v4l2_codec2/common/V4L2ComponentCommon.h9
-rw-r--r--common/include/v4l2_codec2/common/V4L2Device.h14
-rw-r--r--components/V4L2ComponentFactory.cpp40
-rw-r--r--components/V4L2DecodeComponent.cpp13
-rw-r--r--components/V4L2DecodeInterface.cpp39
-rw-r--r--components/include/v4l2_codec2/components/V4L2ComponentFactory.h7
-rw-r--r--components/include/v4l2_codec2/components/V4L2DecodeComponent.h5
-rw-r--r--components/include/v4l2_codec2/components/V4L2DecodeInterface.h4
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;