Commit ac6f2444 authored by Francois Buergisser's avatar Francois Buergisser Committed by Commit Bot

media/gpu/v4l2: Check request support in queue.

The queue's support is currently checked in the video decoder but the
queue should be responsible to check whether it does support requests or not.
This patch moves the check for the request support to the V4L2Queue
constructor.

BUG=chromium:1009921
TEST=ran tast with video.DecodeAccelVDVP8ResolutionSwitch on veyron_minnie-kernelnext.
TEST=ran tast with video.DecodeAccelVDH264ResolutionSwitch on veyron_minnie-kernelnext.
TEST=ran tast with video.DecodeAccelVDVP8 on veyron_minnie-kernelnext.
TEST=ran tast with video.DecodeAccelVDH264 on veyron_minnie-kernelnext.
TEST=ran tast with video.DecodeAccelVDVP8ResolutionSwitch on veyron_minnie.
TEST=ran tast with video.DecodeAccelVDH264ResolutionSwitch on veyron_minnie.
TEST=ran tast with video.DecodeAccelVDVP8 on veyron_minnie.
TEST=ran tast with video.DecodeAccelVDH264 on veyron_minnie.
Signed-off-by: default avatarFrancois Buergisser <fbuergisser@chromium.org>
Change-Id: Icdceab06d3b263d0ce68993b3ee753bd650706dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1880208
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709376}
parent 89de1b10
......@@ -771,6 +771,22 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev,
destroy_cb_(std::move(destroy_cb)),
weak_this_factory_(this) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Check if this queue support requests.
struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs));
reqbufs.count = 0;
reqbufs.type = type;
reqbufs.memory = V4L2_MEMORY_MMAP;
if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
VPLOGF(1) << "Request support checks's VIDIOC_REQBUFS ioctl failed.";
return;
}
if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
supports_requests_ = true;
VLOGF(1) << "Using request API.";
}
}
V4L2Queue::~V4L2Queue() {
......@@ -1081,6 +1097,10 @@ size_t V4L2Queue::QueuedBuffersCount() const {
return queued_buffers_.size();
}
bool V4L2Queue::SupportsRequests() {
return supports_requests_;
}
// This class is used to expose V4L2Queue's constructor to this module. This is
// to ensure that nobody else can create instances of it.
class V4L2QueueFactory {
......
......@@ -338,6 +338,9 @@ class MEDIA_GPU_EXPORT V4L2Queue
// Returns the number of buffers currently queued on this queue.
size_t QueuedBuffersCount() const;
// Returns true if requests are supported by this queue.
bool SupportsRequests();
private:
~V4L2Queue();
......@@ -347,6 +350,8 @@ class MEDIA_GPU_EXPORT V4L2Queue
const enum v4l2_buf_type type_;
enum v4l2_memory memory_ = V4L2_MEMORY_MMAP;
bool is_streaming_ = false;
// Set to true if the queue supports requests.
bool supports_requests_ = false;
size_t planes_count_ = 0;
// Current format as set by SetFormat.
base::Optional<struct v4l2_format> current_format_;
......
......@@ -124,7 +124,7 @@ V4L2StatelessVideoDecoderBackend::~V4L2StatelessVideoDecoderBackend() {
avd_ = nullptr;
}
if (supports_requests_) {
if (input_queue_->SupportsRequests()) {
requests_ = {};
media_fd_.reset();
}
......@@ -133,15 +133,23 @@ V4L2StatelessVideoDecoderBackend::~V4L2StatelessVideoDecoderBackend() {
bool V4L2StatelessVideoDecoderBackend::Initialize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!CheckRequestAPISupport()) {
VPLOGF(1) << "Failed to check request api support.";
return false;
if (input_queue_->SupportsRequests()) {
DCHECK(!media_fd_.is_valid());
// Let's try to open the media device
// TODO(crbug.com/985230): remove this hardcoding, replace with V4L2Device
// integration.
int media_fd = open("/dev/media-dec0", O_RDWR, 0);
if (media_fd < 0) {
VPLOGF(1) << "Failed to open media device.";
return false;
}
media_fd_ = base::ScopedFD(media_fd);
}
// Create codec-specific AcceleratedVideoDecoder.
// TODO(akahuang): Check the profile is supported.
if (profile_ >= H264PROFILE_MIN && profile_ <= H264PROFILE_MAX) {
if (supports_requests_) {
if (input_queue_->SupportsRequests()) {
avd_.reset(new H264Decoder(
std::make_unique<V4L2H264Accelerator>(this, device_.get())));
} else {
......@@ -149,7 +157,7 @@ bool V4L2StatelessVideoDecoderBackend::Initialize() {
std::make_unique<V4L2LegacyH264Accelerator>(this, device_.get())));
}
} else if (profile_ >= VP8PROFILE_MIN && profile_ <= VP8PROFILE_MAX) {
if (supports_requests_) {
if (input_queue_->SupportsRequests()) {
avd_.reset(new VP8Decoder(
std::make_unique<V4L2VP8Accelerator>(this, device_.get())));
} else {
......@@ -164,7 +172,7 @@ bool V4L2StatelessVideoDecoderBackend::Initialize() {
return false;
}
if (supports_requests_ && !AllocateRequests()) {
if (input_queue_->SupportsRequests() && !AllocateRequests()) {
return false;
}
......@@ -252,7 +260,7 @@ V4L2StatelessVideoDecoderBackend::CreateSurface() {
}
scoped_refptr<V4L2DecodeSurface> dec_surface;
if (supports_requests_) {
if (input_queue_->SupportsRequests()) {
DCHECK(!requests_.empty());
base::ScopedFD request = std::move(requests_.front());
requests_.pop();
......@@ -553,39 +561,6 @@ void V4L2StatelessVideoDecoderBackend::ClearPendingRequests(
}
}
bool V4L2StatelessVideoDecoderBackend::CheckRequestAPISupport() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOGF(3);
struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs));
reqbufs.count = 0;
reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
reqbufs.memory = V4L2_MEMORY_MMAP;
if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
VPLOGF(1) << "VIDIOC_REQBUFS ioctl failed.";
return false;
}
if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
supports_requests_ = true;
VLOGF(1) << "Using request API.";
DCHECK(!media_fd_.is_valid());
// Let's try to open the media device
// TODO(crbug.com/985230): remove this hardcoding, replace with V4L2Device
// integration.
int media_fd = open("/dev/media-dec0", O_RDWR, 0);
if (media_fd < 0) {
VPLOGF(1) << "Failed to open media device.";
return false;
}
media_fd_ = base::ScopedFD(media_fd);
} else {
VLOGF(1) << "Using config store.";
}
return true;
}
bool V4L2StatelessVideoDecoderBackend::AllocateRequests() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOGF(3);
......
......@@ -117,8 +117,6 @@ class V4L2StatelessVideoDecoderBackend : public V4L2VideoDecoderBackend,
// Setup the format of V4L2 output buffer, and allocate new buffer set.
bool ChangeResolution();
// Check whether request api is supported or not.
bool CheckRequestAPISupport();
// Allocate necessary request buffers is request api is supported.
bool AllocateRequests();
......@@ -158,8 +156,6 @@ class V4L2StatelessVideoDecoderBackend : public V4L2VideoDecoderBackend,
// Callbacks of EOS buffer passed from Decode().
VideoDecoder::DecodeCB flush_cb_;
// Set to true during Initialize() if the codec driver supports request API.
bool supports_requests_ = false;
// FIFO queue of requests, only used if supports_requests_ is true.
base::queue<base::ScopedFD> requests_;
// Stores the media file descriptor, only used if supports_requests_ is true.
......
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