aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-11-05 09:35:25 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-11-05 09:35:25 +0000
commit892613869887ce2ad9b39364631281ca57f5939d (patch)
treef77228236b9f5dd17fed77ccb5f2cd07da669e37
parente2fcca0783c6a64e15857ef45aac6b130f356621 (diff)
parentc9cd11bc2b4bc5ffff54c1dd021fbffee4e335f1 (diff)
downloadv4l2_codec2-892613869887ce2ad9b39364631281ca57f5939d.tar.gz
Merge "Use dma-buf inode number as buffer unique id" am: c9cd11bc2b
Original change: https://android-review.googlesource.com/c/platform/external/v4l2_codec2/+/1878495 Change-Id: I2de89af152eed42ca64ea6f4dc00ccc2eedd7ae3
-rw-r--r--README.md7
-rw-r--r--plugin_store/Android.bp2
-rw-r--r--plugin_store/C2VdaBqBlockPool.cpp70
-rw-r--r--plugin_store/DrmGrallocHelpers.cpp110
-rw-r--r--plugin_store/include/v4l2_codec2/plugin_store/C2VdaBqBlockPool.h4
-rw-r--r--plugin_store/include/v4l2_codec2/plugin_store/DrmGrallocHelpers.h19
6 files changed, 26 insertions, 186 deletions
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 += \
<path_to_file>:$(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 <errno.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <chrono>
#include <mutex>
@@ -24,7 +27,6 @@
#include <log/log.h>
#include <ui/BufferQueueDefs.h>
-#include <v4l2_codec2/plugin_store/DrmGrallocHelpers.h>
#include <v4l2_codec2/plugin_store/H2BGraphicBufferProducer.h>
#include <v4l2_codec2/plugin_store/V4L2AllocatorId.h>
@@ -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<unique_id_t> 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<unique_id_t>(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<unique_id_t> getHandle(int primeFd) {
- if (!mRenderFd) {
- return std::nullopt;
- }
-
- std::optional<unique_id_t> 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<int> mRenderFd;
- std::set<unique_id_t> mHandles;
-};
-
class C2VdaBqBlockPool::Impl : public std::enable_shared_from_this<C2VdaBqBlockPool::Impl>,
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<size_t>(bufferCount);
@@ -822,7 +791,6 @@ void C2VdaBqBlockPool::Impl::configureProducer(const sp<HGraphicBufferProducer>&
mProducer = nullptr;
mProducerId = 0;
mTrackedGraphicBuffers.reset();
- mDrmHandleManager.closeAllHandles();
return;
}
@@ -931,7 +899,7 @@ bool C2VdaBqBlockPool::Impl::setNotifyBlockAvailableCb(::base::OnceClosure cb) {
std::optional<unique_id_t> 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 <v4l2_codec2/plugin_store/DrmGrallocHelpers.h>
-
-#include <fcntl.h>
-#include <glob.h>
-
-#include <string>
-#include <vector>
-
-#include <cutils/properties.h>
-#include <drm/drm.h>
-#include <log/log.h>
-
-namespace android {
-namespace {
-
-// Return a list of paths that matches |pattern|, the unix style pathname pattern.
-std::vector<std::string> glob(const std::string& pattern) {
- glob_t glob_result;
- memset(&glob_result, 0, sizeof(glob_result));
-
- std::vector<std::string> 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<std::string> 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<int> 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<int>(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<uint32_t> 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<int>(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<unique_id_t> 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 <stdint.h>
-
-#include <optional>
-
-namespace android {
-
-std::optional<int> openRenderFd();
-std::optional<uint32_t> 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