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

media/gpu/v4l2: add and use V4L2Queue::GetVisibleRect()

Getting the visible rectangle is a common operation that will be used by
both the VDA decoder and the VD. Factorize it into a single method.

BUG=b:149663704
TEST=vdatest passing on Hana.

Change-Id: I1d254a7007bcd5919a8c9639b90c72c0f4adacd7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2131431
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarChih-Yu Huang <akahuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756177}
parent 30b2ad18
...@@ -47,6 +47,10 @@ namespace { ...@@ -47,6 +47,10 @@ namespace {
// Maximum number of requests that can be created. // Maximum number of requests that can be created.
constexpr size_t kMaxNumRequests = 32; constexpr size_t kMaxNumRequests = 32;
gfx::Rect V4L2RectToGfxRect(const v4l2_rect& rect) {
return gfx::Rect(rect.left, rect.top, rect.width, rect.height);
}
} // namespace } // namespace
V4L2ExtCtrl::V4L2ExtCtrl(uint32_t id) { V4L2ExtCtrl::V4L2ExtCtrl(uint32_t id) {
...@@ -892,6 +896,46 @@ std::pair<base::Optional<struct v4l2_format>, int> V4L2Queue::GetFormat() { ...@@ -892,6 +896,46 @@ std::pair<base::Optional<struct v4l2_format>, int> V4L2Queue::GetFormat() {
return std::make_pair(format, 0); return std::make_pair(format, 0);
} }
base::Optional<gfx::Rect> V4L2Queue::GetVisibleRect() {
// Some drivers prior to 4.13 only accept the non-MPLANE variant when using
// VIDIOC_G_SELECTION. This block can be removed once we stop supporting
// kernels < 4.13.
// For details, see the note at
// https://www.kernel.org/doc/html/latest/media/uapi/v4l/vidioc-g-selection.html
enum v4l2_buf_type compose_type;
switch (type_) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
compose_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
compose_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
break;
default:
compose_type = type_;
break;
}
struct v4l2_selection selection = {};
selection.type = compose_type;
selection.target = V4L2_SEL_TGT_COMPOSE;
if (device_->Ioctl(VIDIOC_G_SELECTION, &selection) == 0) {
DVQLOGF(3) << "VIDIOC_G_SELECTION is supported";
return V4L2RectToGfxRect(selection.r);
}
// TODO(acourbot) using VIDIOC_G_CROP is considered legacy and can be
// removed once no active devices use it anymore.
DVQLOGF(3) << "Fallback to VIDIOC_G_CROP";
struct v4l2_crop crop = {};
crop.type = type_;
if (device_->Ioctl(VIDIOC_G_CROP, &crop) == 0) {
return V4L2RectToGfxRect(crop.c);
}
VQLOGF(1) << "Failed to get visible rect";
return base::nullopt;
}
size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) { size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!free_buffers_); DCHECK(!free_buffers_);
......
...@@ -309,6 +309,10 @@ class MEDIA_GPU_EXPORT V4L2Queue ...@@ -309,6 +309,10 @@ class MEDIA_GPU_EXPORT V4L2Queue
// is one or not. // is one or not.
std::pair<base::Optional<struct v4l2_format>, int> GetFormat(); std::pair<base::Optional<struct v4l2_format>, int> GetFormat();
// Codec-specific method to get the visible rectangle of the queue, using the
// VIDIOC_G_SELECTION ioctl if available, or VIDIOC_G_CROP as a fallback.
base::Optional<gfx::Rect> GetVisibleRect();
// Allocate |count| buffers for the current format of this queue, with a // Allocate |count| buffers for the current format of this queue, with a
// specific |memory| allocation, and returns the number of buffers allocated // specific |memory| allocation, and returns the number of buffers allocated
// or zero if an error occurred, or if references to any previously allocated // or zero if an error occurred, or if references to any previously allocated
......
...@@ -2147,30 +2147,11 @@ gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize( ...@@ -2147,30 +2147,11 @@ gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize(
const gfx::Size& coded_size) { const gfx::Size& coded_size) {
DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
struct v4l2_rect* visible_rect; auto ret = output_queue_->GetVisibleRect();
struct v4l2_selection selection_arg; if (!ret) {
memset(&selection_arg, 0, sizeof(selection_arg)); return coded_size;
selection_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
selection_arg.target = V4L2_SEL_TGT_COMPOSE;
if (device_->Ioctl(VIDIOC_G_SELECTION, &selection_arg) == 0) {
DVLOGF(3) << "VIDIOC_G_SELECTION is supported";
visible_rect = &selection_arg.r;
} else {
DVLOGF(3) << "Fallback to VIDIOC_G_CROP";
struct v4l2_crop crop_arg;
memset(&crop_arg, 0, sizeof(crop_arg));
crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if (device_->Ioctl(VIDIOC_G_CROP, &crop_arg) != 0) {
VPLOGF(1) << "ioctl() VIDIOC_G_CROP failed";
return coded_size;
}
visible_rect = &crop_arg.c;
} }
gfx::Rect rect = std::move(*ret);
gfx::Rect rect(visible_rect->left, visible_rect->top, visible_rect->width,
visible_rect->height);
DVLOGF(3) << "visible rectangle is " << rect.ToString(); DVLOGF(3) << "visible rectangle is " << rect.ToString();
if (!gfx::Rect(coded_size).Contains(rect)) { if (!gfx::Rect(coded_size).Contains(rect)) {
DVLOGF(3) << "visible rectangle " << rect.ToString() DVLOGF(3) << "visible rectangle " << rect.ToString()
......
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