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 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <unistd.h>
#include <iterator>
#include "base/files/file_util.h"
#include "base/posix/eintr_wrapper.h"
#include "base/trace_event/trace_event.h"
#include "media/gpu/macros.h"
......@@ -172,6 +175,16 @@ bool TegraV4L2Device::Open(Type type, uint32_t /* v4l2_pixfmt */) {
bool TegraV4L2Device::OpenInternal(Type type) {
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) {
case Type::kDecoder:
device_path = kDecoderDevice;
......@@ -208,12 +221,18 @@ std::vector<base::ScopedFD> TegraV4L2Device::GetDmabufsForV4L2Buffer(
size_t num_planes,
enum v4l2_buf_type /* buf_type */) {
DVLOGF(3);
DCHECK(dummy_fd_.is_valid());
std::vector<base::ScopedFD> dmabuf_fds;
// 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
// 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;
}
......
......@@ -87,6 +87,12 @@ class TegraV4L2Device : public V4L2Device {
// The actual device fd.
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
// v4l2_buf_type.
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