From 0006bb541d0489346d8fbd0881742655f20bd186 Mon Sep 17 00:00:00 2001 From: Roman Stratiienko Date: Wed, 3 Nov 2021 11:11:21 +0200 Subject: Use dma-buf inode number as buffer unique id Importing buffer into DRM/KMS just to obtain unique_id is redundant and can cause issues if wrong DRM/KMS device selected. Signed-off-by: Roman Stratiienko Change-Id: I0f20cf8f230f26be4641a85bf1f7ec4d47690494 --- README.md | 7 +- plugin_store/Android.bp | 2 - plugin_store/C2VdaBqBlockPool.cpp | 70 ++++--------- plugin_store/DrmGrallocHelpers.cpp | 110 --------------------- .../v4l2_codec2/plugin_store/C2VdaBqBlockPool.h | 4 + .../v4l2_codec2/plugin_store/DrmGrallocHelpers.h | 19 ---- 6 files changed, 26 insertions(+), 186 deletions(-) delete mode 100644 plugin_store/DrmGrallocHelpers.cpp delete mode 100644 plugin_store/include/v4l2_codec2/plugin_store/DrmGrallocHelpers.h diff --git a/README.md b/README.md index a381864..aa59a40 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ request to the driver via the V4L2 API. * Gralloc support for graphic buffer allocation * ION or Gralloc support for linear buffer allocation -* DRM for buffer identification +* Kernel v5.3+ or [this patch][1] backported for buffer identification * [V4L2 stateful decoding API](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-decoder.html) * [V4L2 encoding API](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-encoder.html) * Widevine DRM for secure playback @@ -47,12 +47,9 @@ PRODUCT_COPY_FILES += \ :$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_c2.xml # Set the customized property of v4l2_codec2, including: -# - The DRM device name and path pattern. # - The maximum concurrent instances for decoder/encoder. # It should be the same as "concurrent-instances" at media_codec_c2.xml. PRODUCT_PROPERTY_OVERRIDES += \ - ro.vendor.v4l2_codec2.drm_device_name=virtio_gpu \ - ro.vendor.v4l2_codec2.drm_device_path=/dev/dri/renderD* \ ro.vendor.v4l2_codec2.decode_concurrent_instances=8 \ ro.vendor.v4l2_codec2.encode_concurrent_instances=8 @@ -364,3 +361,5 @@ PPS NAL units are prepended to IDR frames by enabling the *V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR* control. If the V4L2 driver does not support this control the encoder will manually cache and prepend SPS and PPS NAL units. + +[1]: https://android.googlesource.com/kernel/common/+/ed63bb1d1f8469586006a9ca63c42344401aa2ab diff --git a/plugin_store/Android.bp b/plugin_store/Android.bp index e358378..c6f313c 100644 --- a/plugin_store/Android.bp +++ b/plugin_store/Android.bp @@ -18,7 +18,6 @@ cc_library_shared { srcs: [ "C2VdaBqBlockPool.cpp", "C2VdaPooledBlockPool.cpp", - "DrmGrallocHelpers.cpp", "H2BGraphicBufferProducer.cpp", "V4L2PluginStore.cpp", "VendorAllocatorLoader.cpp", @@ -34,7 +33,6 @@ cc_library_shared { "android.hardware.graphics.bufferqueue@2.0", "libchrome", "libcutils", - "libdrm", "libhardware", "libhidlbase", "libnativewindow", diff --git a/plugin_store/C2VdaBqBlockPool.cpp b/plugin_store/C2VdaBqBlockPool.cpp index 855f389..4a4198f 100644 --- a/plugin_store/C2VdaBqBlockPool.cpp +++ b/plugin_store/C2VdaBqBlockPool.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include +#include #include #include @@ -24,7 +27,6 @@ #include #include -#include #include #include @@ -44,8 +46,6 @@ constexpr int kMaxDequeuedBufferCount = 32u; using namespace std::chrono_literals; -// We use the value of DRM handle as the unique ID of the graphic buffers. -using unique_id_t = uint32_t; // Type for IGBP slot index. using slot_t = int32_t; @@ -54,6 +54,20 @@ using ::android::BufferQueueDefs::NUM_BUFFER_SLOTS; using ::android::hardware::Return; using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0::IProducerListener; +std::optional getDmabufId(int dmabufFd) { + struct stat sb {}; + if (fstat(dmabufFd, &sb) != 0) { + return std::nullopt; + } + + if (sb.st_size == 0) { + ALOGE("Dma-buf size is 0. Please check your kernel is v5.3+"); + return std::nullopt; + } + + return static_cast(sb.st_ino); +} + static c2_status_t asC2Error(status_t err) { switch (err) { case OK: @@ -408,47 +422,6 @@ private: uint64_t mUsageToBeMigrated = 0; }; -class DrmHandleManager { -public: - DrmHandleManager() { mRenderFd = openRenderFd(); } - - ~DrmHandleManager() { - closeAllHandles(); - if (mRenderFd) { - close(*mRenderFd); - } - } - - std::optional getHandle(int primeFd) { - if (!mRenderFd) { - return std::nullopt; - } - - std::optional handle = getDrmHandle(*mRenderFd, primeFd); - // Defer closing the handle until we don't need the buffer to keep the returned DRM handle - // the same. - if (handle) { - mHandles.insert(*handle); - } - return handle; - } - - void closeAllHandles() { - if (!mRenderFd) { - return; - } - - for (const unique_id_t& handle : mHandles) { - closeDrmHandle(*mRenderFd, handle); - } - mHandles.clear(); - } - -private: - std::optional mRenderFd; - std::set mHandles; -}; - class C2VdaBqBlockPool::Impl : public std::enable_shared_from_this, public EventNotifier::Listener { public: @@ -514,9 +487,6 @@ private: TrackedGraphicBuffers mTrackedGraphicBuffers; - // We treat DRM handle as uniqueId of GraphicBuffer. - DrmHandleManager mDrmHandleManager; - // Number of buffers requested on requestNewBufferSet() call. size_t mBuffersRequested = 0u; // Currently requested buffer formats. @@ -673,7 +643,7 @@ status_t C2VdaBqBlockPool::Impl::getFreeSlotLocked(uint32_t width, uint32_t heig return requestStatus; } - const auto uniqueId = mDrmHandleManager.getHandle(slotBuffer->handle->data[0]); + const auto uniqueId = getDmabufId(slotBuffer->handle->data[0]); if (!uniqueId) { ALOGE("%s(): failed to get uniqueId of GraphicBuffer from slot=%d", __func__, *slot); return UNKNOWN_ERROR; @@ -802,7 +772,6 @@ c2_status_t C2VdaBqBlockPool::Impl::requestNewBufferSet(int32_t bufferCount, uin // Release all remained slot buffer references here. CCodec should either cancel or queue its // owned buffers from this set before the next resolution change. mTrackedGraphicBuffers.reset(); - mDrmHandleManager.closeAllHandles(); mBuffersRequested = static_cast(bufferCount); @@ -822,7 +791,6 @@ void C2VdaBqBlockPool::Impl::configureProducer(const sp& mProducer = nullptr; mProducerId = 0; mTrackedGraphicBuffers.reset(); - mDrmHandleManager.closeAllHandles(); return; } @@ -931,7 +899,7 @@ bool C2VdaBqBlockPool::Impl::setNotifyBlockAvailableCb(::base::OnceClosure cb) { std::optional C2VdaBqBlockPool::Impl::getBufferIdFromGraphicBlock( const C2Block2D& block) { - return mDrmHandleManager.getHandle(block.handle()->data[0]); + return getDmabufId(block.handle()->data[0]); } status_t C2VdaBqBlockPool::Impl::allowAllocation(bool allow) { diff --git a/plugin_store/DrmGrallocHelpers.cpp b/plugin_store/DrmGrallocHelpers.cpp deleted file mode 100644 index 0e2cca9..0000000 --- a/plugin_store/DrmGrallocHelpers.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -//#define LOG_NDEBUG 0 -#define LOG_TAG "DrmGrallocHelper" - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -namespace android { -namespace { - -// Return a list of paths that matches |pattern|, the unix style pathname pattern. -std::vector glob(const std::string& pattern) { - glob_t glob_result; - memset(&glob_result, 0, sizeof(glob_result)); - - std::vector paths; - if (glob(pattern.c_str(), GLOB_ERR | GLOB_NOESCAPE, NULL, &glob_result) == 0) { - for (size_t i = 0; i < glob_result.gl_pathc; ++i) { - paths.emplace_back(glob_result.gl_pathv[i]); - } - } - - globfree(&glob_result); - return paths; -} - -std::optional propertyGetString(const char* key) { - char buf[PROPERTY_VALUE_MAX]; - int len = property_get(key, buf, nullptr); - if (len == 0) { - return std::nullopt; - } - return std::string(buf, len); -} - -} // namespace - -std::optional openRenderFd() { - constexpr char kDevNamePropertyKey[] = "ro.vendor.v4l2_codec2.drm_device_name"; - constexpr char kDevPathPropertyKey[] = "ro.vendor.v4l2_codec2.drm_device_path"; - - const auto devName = propertyGetString(kDevNamePropertyKey); - if (!devName) { - ALOGE("Failed to get DRM device name from Android property"); - return std::nullopt; - } - - const auto devPath = propertyGetString(kDevPathPropertyKey).value_or("/dev/dri/renderD*"); - for (const auto filePath : glob(devPath)) { - int fd = open(filePath.c_str(), O_RDWR | O_CLOEXEC); - if (fd < 0) { - continue; - } - - char name[32]; - struct drm_version v; - memset(&v, 0, sizeof(v)); - v.name = name; - v.name_len = sizeof(name); - - if (ioctl(fd, static_cast(DRM_IOCTL_VERSION), &v)) { - close(fd); - continue; - } - if (devName->size() != v.name_len || *devName != name) { - close(fd); - continue; - } - return fd; - } - return std::nullopt; -} - -std::optional getDrmHandle(int renderFd, int primeFd) { - ALOGV("%s(renderFd=%d, primeFd=%u)", __func__, renderFd, primeFd); - - struct drm_prime_handle prime; - memset(&prime, 0, sizeof(prime)); - prime.fd = primeFd; - - if (ioctl(renderFd, static_cast(DRM_IOCTL_PRIME_FD_TO_HANDLE), &prime)) { - ALOGE("Can't translate prime fd %d to handle", prime.fd); - return std::nullopt; - } - return prime.handle; -} - -void closeDrmHandle(int renderFd, uint32_t handle) { - ALOGV("%s(renderFd=%d, handle=%u)", __func__, renderFd, handle); - - struct drm_gem_close gem; - memset(&gem, 0, sizeof(gem)); - gem.handle = handle; - - ioctl(renderFd, DRM_IOCTL_GEM_CLOSE, &gem); -} - -} // namespace android diff --git a/plugin_store/include/v4l2_codec2/plugin_store/C2VdaBqBlockPool.h b/plugin_store/include/v4l2_codec2/plugin_store/C2VdaBqBlockPool.h index fde6299..fe66410 100644 --- a/plugin_store/include/v4l2_codec2/plugin_store/C2VdaBqBlockPool.h +++ b/plugin_store/include/v4l2_codec2/plugin_store/C2VdaBqBlockPool.h @@ -16,6 +16,10 @@ namespace android { +// We use the value of dma-buf inode as the unique ID of the graphic buffers. +using unique_id_t = uint32_t; +std::optional getDmabufId(int dmabufFd); + /** * The BufferQueue-backed block pool design which supports to request arbitrary count of graphic * buffers from IGBP, and use this buffer set among codec component and client. diff --git a/plugin_store/include/v4l2_codec2/plugin_store/DrmGrallocHelpers.h b/plugin_store/include/v4l2_codec2/plugin_store/DrmGrallocHelpers.h deleted file mode 100644 index 46d2967..0000000 --- a/plugin_store/include/v4l2_codec2/plugin_store/DrmGrallocHelpers.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_V4L2_CODEC2_PLUGIN_STORE_STORE_DRM_GRALLOC_HELPERS_H -#define ANDROID_V4L2_CODEC2_PLUGIN_STORE_STORE_DRM_GRALLOC_HELPERS_H - -#include - -#include - -namespace android { - -std::optional openRenderFd(); -std::optional getDrmHandle(int renderFd, int primeFd); -void closeDrmHandle(int renderFd, uint32_t handle); - -} // namespace android -#endif // ANDROID_V4L2_CODEC2_PLUGIN_STORE_STORE_DRM_GRALLOC_HELPERS_H -- cgit v1.2.3