diff --git a/README.md b/README.md
index a381864d59499fc3aa3118785711b2e97645f920..aa59a409ebf9d1fe57e5c89e0a818ce324249182 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 e358378a499e13669cd8f21b6da681196bdc5a0b..c6f313c776dce62573399f6b51fdcde8ebbc3281 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 855f389b14425084ea021d0618eab27b07826b35..4a4198fb4f1950709c98317a3b18e932cf8665a4 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 0e2cca967450428aa6211250f25cb520b862ef02..0000000000000000000000000000000000000000
--- 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 fde62998a16aa7b9ddb147affa9d6fe0df3f1aeb..fe66410ccebbac3e343e56e214ba8be5e047d383 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 46d29671bddb81b9aaa1393af990203b4bf35afb..0000000000000000000000000000000000000000
--- 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