Commit 36ffa4fd authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu: Notify frame size adjusted by ARC++

ARC++ allocates video frame buffer using gralloc. The requested frame size is
specified by ProvidePictureBuffers(). Gralloc possibility adjusts the requested
frame size. Chrome has to be informed the adjusted frame size and work with the
frame size.

Bug: 979115
Test: CtsMediaTestCases on kevin
Test: CtsMediaTestCases on atlas
Change-Id: I91c8aa3f64e8a8dba0b6c62ab18918fc0c7d5a24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1694962
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676820}
parent 31ca7318
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Next MinVersion: 4 // Next MinVersion: 5
// This file defines the mojo interface between Android and Chromium for video // This file defines the mojo interface between Android and Chromium for video
// decoding. Any Mojo callee that returns a value does so by callback. // decoding. Any Mojo callee that returns a value does so by callback.
...@@ -78,7 +78,7 @@ struct VideoDecodeAcceleratorConfig { ...@@ -78,7 +78,7 @@ struct VideoDecodeAcceleratorConfig {
// the dummy buffer. // the dummy buffer.
// //
// Deprecated method IDs: 3, 7, 8 // Deprecated method IDs: 3, 7, 8
// Next method ID: 10 // Next method ID: 11
interface VideoDecodeAccelerator { interface VideoDecodeAccelerator {
[Extensible] [Extensible]
enum Result { enum Result {
...@@ -104,7 +104,13 @@ interface VideoDecodeAccelerator { ...@@ -104,7 +104,13 @@ interface VideoDecodeAccelerator {
// Sets the number of output picture buffers. // Sets the number of output picture buffers.
// This releases any buffers in use/imported previously. // This releases any buffers in use/imported previously.
AssignPictureBuffers@2(uint32 count); AssignPictureBuffersDeprecated@2(uint32 count);
// Sets the number of output picture buffers. |size| is the frame size
// adjusted by Android.
// This releases any buffers in use/imported previously.
[MinVersion=4]
AssignPictureBuffers@10(uint32 count, Size size);
// Imports a buffer to be used by the accelerator with specified // Imports a buffer to be used by the accelerator with specified
// |picture_buffer_id|. // |picture_buffer_id|.
......
...@@ -438,7 +438,13 @@ void GpuArcVideoDecodeAccelerator::Decode( ...@@ -438,7 +438,13 @@ void GpuArcVideoDecodeAccelerator::Decode(
} }
} }
void GpuArcVideoDecodeAccelerator::AssignPictureBuffers(uint32_t count) { void GpuArcVideoDecodeAccelerator::AssignPictureBuffersDeprecated(
uint32_t count) {
AssignPictureBuffers(count, pending_coded_size_);
}
void GpuArcVideoDecodeAccelerator::AssignPictureBuffers(uint32_t count,
const gfx::Size& size) {
VLOGF(2) << "count=" << count; VLOGF(2) << "count=" << count;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!vda_) { if (!vda_) {
...@@ -453,7 +459,7 @@ void GpuArcVideoDecodeAccelerator::AssignPictureBuffers(uint32_t count) { ...@@ -453,7 +459,7 @@ void GpuArcVideoDecodeAccelerator::AssignPictureBuffers(uint32_t count) {
return; return;
} }
coded_size_ = pending_coded_size_; coded_size_ = size;
std::vector<media::PictureBuffer> buffers; std::vector<media::PictureBuffer> buffers;
for (uint32_t id = 0; id < count; ++id) { for (uint32_t id = 0; id < count; ++id) {
buffers.push_back( buffers.push_back(
......
...@@ -64,7 +64,8 @@ class GpuArcVideoDecodeAccelerator ...@@ -64,7 +64,8 @@ class GpuArcVideoDecodeAccelerator
mojom::VideoDecodeClientPtr client, mojom::VideoDecodeClientPtr client,
InitializeCallback callback) override; InitializeCallback callback) override;
void Decode(mojom::BitstreamBufferPtr bitstream_buffer) override; void Decode(mojom::BitstreamBufferPtr bitstream_buffer) override;
void AssignPictureBuffers(uint32_t count) override; void AssignPictureBuffersDeprecated(uint32_t count) override;
void AssignPictureBuffers(uint32_t count, const gfx::Size& size) override;
void ImportBufferForPicture(int32_t picture_buffer_id, void ImportBufferForPicture(int32_t picture_buffer_id,
mojom::HalPixelFormat format, mojom::HalPixelFormat format,
mojo::ScopedHandle handle, mojo::ScopedHandle handle,
......
...@@ -508,6 +508,8 @@ bool V4L2SliceVideoDecodeAccelerator::CreateOutputBuffers() { ...@@ -508,6 +508,8 @@ bool V4L2SliceVideoDecodeAccelerator::CreateOutputBuffers() {
DCHECK_GT(num_pictures, 0u); DCHECK_GT(num_pictures, 0u);
DCHECK(!pic_size.IsEmpty()); DCHECK(!pic_size.IsEmpty());
// Since VdaVideoDeecoder doesn't allocate PictureBuffer with size adjusted by
// itself, we have to adjust here.
struct v4l2_format format; struct v4l2_format format;
memset(&format, 0, sizeof(format)); memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
...@@ -1320,6 +1322,7 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers( ...@@ -1320,6 +1322,7 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers(
void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask( void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
const std::vector<PictureBuffer>& buffers) { const std::vector<PictureBuffer>& buffers) {
VLOGF(2); VLOGF(2);
DCHECK(!output_streamon_);
DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, kAwaitingPictureBuffers); DCHECK_EQ(state_, kAwaitingPictureBuffers);
TRACE_EVENT1("media,gpu", "V4L2SVDA::AssignPictureBuffersTask", TRACE_EVENT1("media,gpu", "V4L2SVDA::AssignPictureBuffersTask",
...@@ -1338,6 +1341,41 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask( ...@@ -1338,6 +1341,41 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
return; return;
} }
// If a client allocate a different frame size, S_FMT should be called with
// the size.
if (coded_size_ != buffers[0].size()) {
const auto& new_frame_size = buffers[0].size();
v4l2_format format = {};
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
format.fmt.pix_mp.width = new_frame_size.width();
format.fmt.pix_mp.height = new_frame_size.height();
format.fmt.pix_mp.pixelformat = output_format_fourcc_;
format.fmt.pix_mp.num_planes = output_planes_count_;
if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0) {
VPLOGF(1) << "Failed with frame size adjusted by client: "
<< new_frame_size.ToString();
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
}
coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
// If size specified by ProvidePictureBuffers() is adjusted by the client,
// the size must not be adjusted by a v4l2 driver again.
if (coded_size_ != new_frame_size) {
VLOGF(1) << "The size of PictureBuffer is invalid."
<< " size adjusted by the client = " << new_frame_size.ToString()
<< " size adjusted by a driver = " << coded_size_.ToString();
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
if (!gfx::Rect(coded_size_).Contains(gfx::Rect(decoder_->GetPicSize()))) {
VLOGF(1) << "Got invalid adjusted coded size: " << coded_size_.ToString();
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
}
// Allocate the output buffers. // Allocate the output buffers.
struct v4l2_requestbuffers reqbufs; struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs)); memset(&reqbufs, 0, sizeof(reqbufs));
...@@ -1358,8 +1396,6 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask( ...@@ -1358,8 +1396,6 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
DCHECK(output_buffer_map_.empty()); DCHECK(output_buffer_map_.empty());
output_buffer_map_.resize(buffers.size()); output_buffer_map_.resize(buffers.size());
for (size_t i = 0; i < output_buffer_map_.size(); ++i) { for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
DCHECK(buffers[i].size() == coded_size_);
OutputRecord& output_record = output_buffer_map_[i]; OutputRecord& output_record = output_buffer_map_[i];
DCHECK(!output_record.at_device); DCHECK(!output_record.at_device);
DCHECK(!output_record.at_client); DCHECK(!output_record.at_client);
......
...@@ -639,6 +639,9 @@ void V4L2VideoDecodeAccelerator::ImportBufferForPictureTask( ...@@ -639,6 +639,9 @@ void V4L2VideoDecodeAccelerator::ImportBufferForPictureTask(
return; 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( int plane_horiz_bits_per_pixel = VideoFrame::PlaneHorizontalBitsPerPixel(
V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), 0); V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), 0);
if (plane_horiz_bits_per_pixel == 0 || if (plane_horiz_bits_per_pixel == 0 ||
......
...@@ -626,7 +626,8 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers( ...@@ -626,7 +626,8 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
buffers.size() >= requested_num_pics_, buffers.size() >= requested_num_pics_,
"Got an invalid number of picture buffers. (Got " << buffers.size() "Got an invalid number of picture buffers. (Got " << buffers.size()
<< ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, ); << ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, );
DCHECK(requested_pic_size_ == buffers[0].size()); // requested_pic_size_ can be adjusted by VDA client.
requested_pic_size_ = buffers[0].size();
va_surface_format_ = GetVaFormatForVideoCodecProfile(profile_); va_surface_format_ = GetVaFormatForVideoCodecProfile(profile_);
std::vector<VASurfaceID> va_surface_ids; std::vector<VASurfaceID> va_surface_ids;
...@@ -646,8 +647,6 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers( ...@@ -646,8 +647,6 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
} }
for (size_t i = 0; i < buffers.size(); ++i) { for (size_t i = 0; i < buffers.size(); ++i) {
DCHECK(requested_pic_size_ == buffers[i].size());
// If we aren't in BufferAllocationMode::kNone, this |picture| is // If we aren't in BufferAllocationMode::kNone, this |picture| is
// only used as a copy destination. Therefore, the VaapiWrapper used and // only used as a copy destination. Therefore, the VaapiWrapper used and
// owned by |picture| is |vpp_vaapi_wrapper_|. // owned by |picture| is |vpp_vaapi_wrapper_|.
......
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