Commit 685bf015 authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

V4L2SVD: Allocate video frame with frame size adjusted by a video driver

The alignment to width and height is changed by codec. The v4l2 driver returns
a width and height with taking into that account. On the other hand, gbm doesn't
know about codec in the allocation. This causes gbm allocates a smaller or
larger buffer than a video driver expects. A small buffer is defintely problem.
A larger buffer is problem if a v4l2 pixel format is single planar. If there is
an extra data between planes unexpected by a driver, the driver reads the next
plane from the wrong position because we cannot specify offset for each plane
with a single planar pixel format. This CL resolves this issue by asking minigbm
to allocate a buffer with width and size already adjusted by a video driver.

Bug: 979115
Test: video_decode_accelerator_tests on kevin
Change-Id: Ibe865530547055256015f9e734e31cd5ed6fbd0f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1730910
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarChih-Yu Huang <akahuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#683899}
parent 01f73dc8
...@@ -426,8 +426,8 @@ bool V4L2SliceVideoDecoder::SetupInputFormat(uint32_t input_format_fourcc) { ...@@ -426,8 +426,8 @@ bool V4L2SliceVideoDecoder::SetupInputFormat(uint32_t input_format_fourcc) {
} }
base::Optional<struct v4l2_format> base::Optional<struct v4l2_format>
V4L2SliceVideoDecoder::SetFormatOnOutputQueue(uint32_t format_fourcc, V4L2SliceVideoDecoder::SetV4L2FormatOnOutputQueue(uint32_t format_fourcc,
const gfx::Size& size) { const gfx::Size& size) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
struct v4l2_format format = {}; struct v4l2_format format = {};
...@@ -457,19 +457,26 @@ base::Optional<VideoFrameLayout> V4L2SliceVideoDecoder::SetupOutputFormat( ...@@ -457,19 +457,26 @@ base::Optional<VideoFrameLayout> V4L2SliceVideoDecoder::SetupOutputFormat(
if (!device_->CanCreateEGLImageFrom(format_fourcc)) if (!device_->CanCreateEGLImageFrom(format_fourcc))
continue; continue;
base::Optional<struct v4l2_format> format =
SetV4L2FormatOnOutputQueue(format_fourcc, size);
if (!format)
continue;
// S_FMT is successful. Next make sure VFPool can allocate video frames with
// width and height adjusted by a video driver.
gfx::Size adjusted_size(format->fmt.pix_mp.width,
format->fmt.pix_mp.height);
// Make sure VFPool can allocate video frames with width and height. // Make sure VFPool can allocate video frames with width and height.
auto frame_layout = auto frame_layout =
UpdateVideoFramePoolFormat(format_fourcc, size, visible_rect); UpdateVideoFramePoolFormat(format_fourcc, adjusted_size, visible_rect);
if (!frame_layout) { if (frame_layout) {
continue; if (frame_layout->coded_size() != adjusted_size) {
} VLOGF(1) << "The size adjusted by VFPool is different from one "
<< "adjusted by a video driver";
continue;
}
// Next S_FMT with the size adjusted by VFPool.
gfx::Size adjusted_size(frame_layout->planes()[0].stride,
frame_layout->coded_size().height());
base::Optional<struct v4l2_format> format =
SetFormatOnOutputQueue(format_fourcc, adjusted_size);
if (format) {
num_output_planes_ = format->fmt.pix_mp.num_planes; num_output_planes_ = format->fmt.pix_mp.num_planes;
return frame_layout; return frame_layout;
} }
......
...@@ -143,7 +143,7 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder, ...@@ -143,7 +143,7 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder,
// Call VIDIOC_S_FMT with |format_fourcc| and |size|. Returns v4l2_format // Call VIDIOC_S_FMT with |format_fourcc| and |size|. Returns v4l2_format
// returned by VIDIOC_S_FMT on success, otherwise returns base::nullopt. // returned by VIDIOC_S_FMT on success, otherwise returns base::nullopt.
// This should be called only from SetupOutputFormat(). // This should be called only from SetupOutputFormat().
base::Optional<struct v4l2_format> SetFormatOnOutputQueue( base::Optional<struct v4l2_format> SetV4L2FormatOnOutputQueue(
uint32_t format_fourcc, uint32_t format_fourcc,
const gfx::Size& size); const gfx::Size& size);
// Setup format for output queue. This function sets output format on output // Setup format for output queue. This function sets output format on output
......
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