Commit bc5805f3 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Commit Bot

media/gpu/v4l2/tegra: return dummy, valid FDs when exporting DMAbuf

crrev.com/c/1982499 started passing NativePixmapHandles to the GL import
methods instead of raw DMAbuf FDs without layout information. But
creating a NativePixmapHandles involves duplicating the FDs of a frame ;
something that would fail on Tegra which passed invalid FDs that were to
be ignored during import.

Fix this by returning a dummy FD created from pipe() instead of an
invalid one. The dummy FD is not any more useful, but it can be
duplicated safely.

BUG=b:148105252
TEST=video_decode_accelerator_tests passing on nyan_big.

Change-Id: Ifda5f98d8383f4883494d13708a45783149810f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2016817Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735334}
parent d99de619
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <unistd.h>
#include <iterator>
#include "base/files/file_util.h"
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "media/gpu/macros.h" #include "media/gpu/macros.h"
...@@ -172,6 +175,16 @@ bool TegraV4L2Device::Open(Type type, uint32_t /* v4l2_pixfmt */) { ...@@ -172,6 +175,16 @@ bool TegraV4L2Device::Open(Type type, uint32_t /* v4l2_pixfmt */) {
bool TegraV4L2Device::OpenInternal(Type type) { bool TegraV4L2Device::OpenInternal(Type type) {
const char* device_path = nullptr; const char* device_path = nullptr;
// Create the dummy FD upon first open.
if (!dummy_fd_.is_valid()) {
base::ScopedFD dummy_write_fd_;
if (!base::CreatePipe(&dummy_fd_, &dummy_write_fd_, false)) {
VPLOGF(1) << "Error creating dummy file descriptors";
return false;
}
}
switch (type) { switch (type) {
case Type::kDecoder: case Type::kDecoder:
device_path = kDecoderDevice; device_path = kDecoderDevice;
...@@ -208,12 +221,18 @@ std::vector<base::ScopedFD> TegraV4L2Device::GetDmabufsForV4L2Buffer( ...@@ -208,12 +221,18 @@ std::vector<base::ScopedFD> TegraV4L2Device::GetDmabufsForV4L2Buffer(
size_t num_planes, size_t num_planes,
enum v4l2_buf_type /* buf_type */) { enum v4l2_buf_type /* buf_type */) {
DVLOGF(3); DVLOGF(3);
DCHECK(dummy_fd_.is_valid());
std::vector<base::ScopedFD> dmabuf_fds; std::vector<base::ScopedFD> dmabuf_fds;
// Tegra does not actually provide dmabuf fds currently. Fill the vector with // Tegra does not actually provide dmabuf fds currently. Fill the vector with
// invalid descriptors to prevent the caller from failing on an empty vector // dummy descriptors to prevent the caller from failing on an empty vector
// being returned. TegraV4L2Device::CreateEGLImage() will ignore the invalid // being returned. TegraV4L2Device::CreateEGLImage() will ignore the invalid
// descriptors and create images based on V4L2 index passed to it. // descriptors and create images based on V4L2 index passed to it.
dmabuf_fds.resize(num_planes); std::generate_n(std::back_inserter(dmabuf_fds), num_planes, [this]() {
int fd = HANDLE_EINTR(dup(dummy_fd_.get()));
DPLOG_IF(ERROR, fd < 0) << "Error duplicating fake DMAbuf FD";
return base::ScopedFD(fd);
});
return dmabuf_fds; return dmabuf_fds;
} }
......
...@@ -87,6 +87,12 @@ class TegraV4L2Device : public V4L2Device { ...@@ -87,6 +87,12 @@ class TegraV4L2Device : public V4L2Device {
// The actual device fd. // The actual device fd.
int device_fd_ = -1; int device_fd_ = -1;
// Dummy FD returned as fake DMABuf FD by GetDmabufsForV4L2Buffer(). Tegra
// is the only platform that does not support DMABufs, but upper layers still
// expect valid FDs that can be duplicated, passed around, and closed. So
// we just return fake DMAbuf FDs that are duplicates of this one.
base::ScopedFD dummy_fd_;
// The v4l2_format cache passed to the driver via VIDIOC_S_FMT. The key is // The v4l2_format cache passed to the driver via VIDIOC_S_FMT. The key is
// v4l2_buf_type. // v4l2_buf_type.
std::map<enum v4l2_buf_type, struct v4l2_format> v4l2_format_cache_; std::map<enum v4l2_buf_type, struct v4l2_format> v4l2_format_cache_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment