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

media/gpu/v4l2: add V4L2Queue::TryFormat()

We were using SetFormat() when we wanted to just test the availability
of a given format on a device. This is a bit misleading for the reader.

Implement and use TryFormat(), which properly uses the TRY_FORMAT ioctl,
and use it where relevant.

BUG=None
TEST=video.DecodeAccel.h264 passed on Trogdor

Change-Id: I223a2911451bae753e8560180ccdaa5a3502a1db
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422103
Commit-Queue: Fritz Koenig <frkoenig@chromium.org>
Reviewed-by: default avatarFritz Koenig <frkoenig@chromium.org>
Auto-Submit: Alexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809404}
parent 52122389
......@@ -52,6 +52,22 @@ gfx::Rect V4L2RectToGfxRect(const v4l2_rect& rect) {
return gfx::Rect(rect.left, rect.top, rect.width, rect.height);
}
struct v4l2_format BuildV4L2Format(const enum v4l2_buf_type type,
uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size) {
struct v4l2_format format;
memset(&format, 0, sizeof(format));
format.type = type;
format.fmt.pix_mp.pixelformat = fourcc;
format.fmt.pix_mp.width = size.width();
format.fmt.pix_mp.height = size.height();
format.fmt.pix_mp.num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(fourcc);
format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
return format;
}
} // namespace
V4L2ExtCtrl::V4L2ExtCtrl(uint32_t id) {
......@@ -922,13 +938,7 @@ V4L2Queue::~V4L2Queue() {
base::Optional<struct v4l2_format> V4L2Queue::SetFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size) {
struct v4l2_format format = {};
format.type = type_;
format.fmt.pix_mp.pixelformat = fourcc;
format.fmt.pix_mp.width = size.width();
format.fmt.pix_mp.height = size.height();
format.fmt.pix_mp.num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(fourcc);
format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size);
if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0 ||
format.fmt.pix_mp.pixelformat != fourcc) {
VPQLOGF(2) << "Failed to set format (format_fourcc=0x" << std::hex << fourcc
......@@ -940,6 +950,20 @@ base::Optional<struct v4l2_format> V4L2Queue::SetFormat(uint32_t fourcc,
return current_format_;
}
base::Optional<struct v4l2_format> V4L2Queue::TryFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size) {
struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size);
if (device_->Ioctl(VIDIOC_TRY_FMT, &format) != 0 ||
format.fmt.pix_mp.pixelformat != fourcc) {
VPQLOGF(2) << "Tried format not supported (format_fourcc=0x" << std::hex
<< fourcc << ")";
return base::nullopt;
}
return format;
}
std::pair<base::Optional<struct v4l2_format>, int> V4L2Queue::GetFormat() {
struct v4l2_format format;
memset(&format, 0, sizeof(format));
......
......@@ -308,6 +308,15 @@ class MEDIA_GPU_EXPORT V4L2Queue
size_t buffer_size)
WARN_UNUSED_RESULT;
// Identical to |SetFormat|, but does not actually apply the format, and can
// be called anytime.
// Returns an adjusted V4L2 format if |fourcc| is supported by the queue, or
// |nullopt| if |fourcc| is not supported or an ioctl error happened.
base::Optional<struct v4l2_format> TryFormat(uint32_t fourcc,
const gfx::Size& size,
size_t buffer_size)
WARN_UNUSED_RESULT;
// Returns the currently set format on the queue. The result is returned as
// a std::pair where the first member is the format, or base::nullopt if the
// format could not be obtained due to an ioctl error. The second member is
......
......@@ -292,7 +292,7 @@ bool V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
}
base::Optional<struct v4l2_format> format =
output_queue_->SetFormat(pixfmt, size, 0);
output_queue_->TryFormat(pixfmt, size, 0);
if (!format)
continue;
......
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