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

media/gpu/v4l2svda: use buffer stride information from ARC++

ARC++ imported buffers can use a different stride than the one requested
by ProvidePictureBuffers(). Make sure to update the buffer stride at the
time of the first buffer import, and create the image processor at that
time.

Bug: b:139901663
Test: Video playback in Chromium and ARC++ on Kukui.
Change-Id: I65a26fae11f92bd240a7c32ead2fdb69c20d5377
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1832126
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Auto-Submit: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701935}
parent f9eba2b9
......@@ -1375,9 +1375,12 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
DCHECK(output_wait_map_.empty());
output_buffer_map_.resize(buffers.size());
if (image_processor_device_ && !CreateImageProcessor()) {
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
// In import mode we will create the IP when importing the first buffer.
if (image_processor_device_ && output_mode_ == Config::OutputMode::ALLOCATE) {
if (!CreateImageProcessor()) {
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
}
}
// Reserve all buffers until ImportBufferForPictureTask() is called
......@@ -1426,8 +1429,11 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
}
}
ImportBufferForPictureTask(output_record.picture_id,
std::move(passed_dmabuf_fds));
int plane_horiz_bits_per_pixel = VideoFrame::PlaneHorizontalBitsPerPixel(
V4L2Device::V4L2PixFmtToVideoPixelFormat(gl_image_format_fourcc_), 0);
ImportBufferForPictureTask(
output_record.picture_id, std::move(passed_dmabuf_fds),
gl_image_size_.width() * plane_horiz_bits_per_pixel / 8);
} // else we'll get triggered via ImportBufferForPicture() from client.
DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id;
}
......@@ -1544,12 +1550,14 @@ void V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureForImportTask(
dmabuf_fds.pop_back();
}
ImportBufferForPictureTask(picture_buffer_id, std::move(dmabuf_fds));
ImportBufferForPictureTask(picture_buffer_id, std::move(dmabuf_fds),
handle.planes[0].stride);
}
void V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask(
int32_t picture_buffer_id,
std::vector<base::ScopedFD> passed_dmabuf_fds) {
std::vector<base::ScopedFD> passed_dmabuf_fds,
int32_t stride) {
DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id;
DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
......@@ -1577,6 +1585,34 @@ void V4L2SliceVideoDecodeAccelerator::ImportBufferForPictureTask(
return;
}
// TODO(crbug.com/982172): This must be done in AssignPictureBuffers().
// However the size of PictureBuffer might not be adjusted by ARC++. So we
// keep this until ARC++ side is fixed.
int plane_horiz_bits_per_pixel = VideoFrame::PlaneHorizontalBitsPerPixel(
V4L2Device::V4L2PixFmtToVideoPixelFormat(gl_image_format_fourcc_), 0);
if (plane_horiz_bits_per_pixel == 0 ||
(stride * 8) % plane_horiz_bits_per_pixel != 0) {
VLOGF(1) << "Invalid format " << gl_image_format_fourcc_ << " or stride "
<< stride;
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
int adjusted_coded_width = stride * 8 / plane_horiz_bits_per_pixel;
if (image_processor_device_ && !image_processor_) {
DCHECK_EQ(kAwaitingPictureBuffers, state_);
// This is the first buffer import. Create the image processor and change
// the decoder state. The client may adjust the coded width. We don't have
// the final coded size in AssignPictureBuffers yet. Use the adjusted coded
// width to create the image processor.
DVLOGF(3) << "Original gl_image_size=" << gl_image_size_.ToString()
<< ", adjusted coded width=" << adjusted_coded_width;
DCHECK_GE(adjusted_coded_width, gl_image_size_.width());
gl_image_size_.set_width(adjusted_coded_width);
if (!CreateImageProcessor())
return;
}
DCHECK_EQ(gl_image_size_.width(), adjusted_coded_width);
// If in import mode, build output_frame from the passed DMABUF FDs.
if (output_mode_ == Config::OutputMode::IMPORT) {
DCHECK_EQ(gl_image_planes_count_, passed_dmabuf_fds.size());
......
......@@ -265,10 +265,11 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
// Use buffer backed by dmabuf file descriptors in |passed_dmabuf_fds| for the
// OutputRecord associated with |picture_buffer_id|, taking ownership of the
// file descriptors.
void ImportBufferForPictureTask(
int32_t picture_buffer_id,
std::vector<base::ScopedFD> passed_dmabuf_fds);
// file descriptors. |stride| is the number of bytes from one row of pixels
// to the next row.
void ImportBufferForPictureTask(int32_t picture_buffer_id,
std::vector<base::ScopedFD> passed_dmabuf_fds,
int32_t stride);
// Check that |planes| and |dmabuf_fds| are valid in import mode and call
// ImportBufferForPictureTask.
......
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