Commit 5f2abb9c authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/v4l2VEA: Create GpuMemoryBuffer for output of IP

V4L2VEA creates V4L2IP for a pixel format conversion. The
destination buffer is either memory-based VideoFrame or
Dmabuf-backed VideoFrame created by V4L2IP internally.

This adds GpuMemoryBuffer-based VideoFrame for the
destination buffer. The GpuMemoryBuffer is created by
V4L2VEA.

Bug: 1033799
Test: VEA test on kukui
Change-Id: I2284301e6d1ae9334d1b38637b62b0d04d808f7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2022562
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarJeffrey Kardatzke <jkardatzke@google.com>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740584}
parent 596a14b2
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "base/task/task_traits.h" #include "base/task/task_traits.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "media/base/bitstream_buffer.h" #include "media/base/bitstream_buffer.h"
#include "media/base/color_plane_layout.h" #include "media/base/color_plane_layout.h"
#include "media/base/scopedfd_helper.h" #include "media/base/scopedfd_helper.h"
...@@ -317,28 +318,30 @@ bool V4L2VideoEncodeAccelerator::CreateImageProcessor( ...@@ -317,28 +318,30 @@ bool V4L2VideoEncodeAccelerator::CreateImageProcessor(
DCHECK_NE(input_layout.format(), output_layout.format()); DCHECK_NE(input_layout.format(), output_layout.format());
// Convert from |config.input_format| + |input_visible_rect| to // Convert from |config.input_format| + |input_visible_rect| to
// |device_input_layout_->format()| + |output_visible_rect|, requiring the // |device_input_layout_->format()| + |output_visible_rect|.
// output buffers to be of at least |device_input_layout_->coded_size()|. // The storage type of VideoFrame given on Encode() must be
// |input_storage_type| can be STORAGE_SHMEM and STORAGE_MOJO_SHARED_BUFFER. // STORAGE_GPU_MEMORY_BUFFER if |input_storage_type| is
// However, it doesn't matter VideoFrame::STORAGE_OWNED_MEMORY is specified // STORAGE_GPU_MEMORY_BUFFER, but any VideoFrame::IsMappable() storage_type is
// for |input_storage_type| here, as long as VideoFrame on Process()'s data // allowed if |input_storage_type| is STORAGE_OWNED_MEMORY.
// can be accessed by VideoFrame::data(). VideoFrame::StorageType input_storage_type =
native_input_mode_ ? VideoFrame::STORAGE_GPU_MEMORY_BUFFER
: VideoFrame::STORAGE_OWNED_MEMORY;
auto input_config = VideoFrameLayoutToPortConfig( auto input_config = VideoFrameLayoutToPortConfig(
input_layout, input_visible_rect, {VideoFrame::STORAGE_OWNED_MEMORY}); input_layout, input_visible_rect, {input_storage_type});
if (!input_config) if (!input_config)
return false; return false;
auto output_config = VideoFrameLayoutToPortConfig( auto output_config =
output_layout, output_visible_rect, VideoFrameLayoutToPortConfig(output_layout, output_visible_rect,
{VideoFrame::STORAGE_DMABUFS, VideoFrame::STORAGE_OWNED_MEMORY}); {VideoFrame::STORAGE_GPU_MEMORY_BUFFER,
VideoFrame::STORAGE_OWNED_MEMORY});
if (!output_config) if (!output_config)
return false; return false;
image_processor_ = ImageProcessorFactory::Create( image_processor_ = ImageProcessorFactory::Create(
*input_config, *output_config, *input_config, *output_config,
// Try OutputMode::ALLOCATE first because we want v4l2IP chooses {ImageProcessor::OutputMode::IMPORT,
// ALLOCATE mode. For libyuvIP, it accepts only IMPORT. ImageProcessor::OutputMode::ALLOCATE},
{ImageProcessor::OutputMode::ALLOCATE,
ImageProcessor::OutputMode::IMPORT},
kImageProcBufferCount, encoder_task_runner_, kImageProcBufferCount, encoder_task_runner_,
base::BindRepeating(&V4L2VideoEncodeAccelerator::ImageProcessorError, base::BindRepeating(&V4L2VideoEncodeAccelerator::ImageProcessorError,
weak_this_)); weak_this_));
...@@ -377,26 +380,43 @@ bool V4L2VideoEncodeAccelerator::AllocateImageProcessorOutputBuffers( ...@@ -377,26 +380,43 @@ bool V4L2VideoEncodeAccelerator::AllocateImageProcessorOutputBuffers(
return true; return true;
} }
image_processor_output_buffers_.resize(count);
const ImageProcessor::PortConfig& output_config = const ImageProcessor::PortConfig& output_config =
image_processor_->output_config(); image_processor_->output_config();
if (output_config.storage_type() == VideoFrame::STORAGE_GPU_MEMORY_BUFFER &&
!image_processor_gmb_factory_) {
image_processor_gmb_factory_ =
gpu::GpuMemoryBufferFactory::CreateNativeType(nullptr);
if (!image_processor_gmb_factory_) {
VLOGF(1) << "Failed to create GpuMemoryBufferFactory";
return false;
}
}
image_processor_output_buffers_.resize(count);
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
switch (output_config.storage_type()) { switch (output_config.storage_type()) {
case VideoFrame::STORAGE_OWNED_MEMORY: case VideoFrame::STORAGE_OWNED_MEMORY:
image_processor_output_buffers_[i] = VideoFrame::CreateFrameWithLayout( image_processor_output_buffers_[i] = VideoFrame::CreateFrameWithLayout(
*device_input_layout_, output_config.visible_rect, *device_input_layout_, output_config.visible_rect,
output_config.visible_rect.size(), base::TimeDelta(), true); output_config.visible_rect.size(), base::TimeDelta(), true);
if (!image_processor_output_buffers_[i]) {
VLOG(1) << "Failed to create VideoFrame";
return false;
}
break; break;
// TODO(crbug.com/910590): Support VideoFrame::STORAGE_DMABUFS. case VideoFrame::STORAGE_GPU_MEMORY_BUFFER:
image_processor_output_buffers_[i] = CreateGpuMemoryBufferVideoFrame(
image_processor_gmb_factory_.get(),
output_config.fourcc.ToVideoPixelFormat(), output_config.size,
output_config.visible_rect, output_config.visible_rect.size(),
base::TimeDelta(),
gfx::BufferUsage::SCANOUT_VEA_READ_CAMERA_AND_CPU_READ_WRITE);
break;
default: default:
VLOGF(1) << "Unsupported output storage type of image processor: " VLOGF(1) << "Unsupported output storage type of image processor: "
<< output_config.storage_type(); << output_config.storage_type();
return false; return false;
} }
if (!image_processor_output_buffers_[i]) {
VLOGF(1) << "Failed to create VideoFrame";
return false;
}
} }
return true; return true;
} }
...@@ -405,7 +425,7 @@ bool V4L2VideoEncodeAccelerator::InitInputMemoryType(const Config& config) { ...@@ -405,7 +425,7 @@ bool V4L2VideoEncodeAccelerator::InitInputMemoryType(const Config& config) {
DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
if (image_processor_) { if (image_processor_) {
const auto storage_type = image_processor_->output_config().storage_type(); const auto storage_type = image_processor_->output_config().storage_type();
if (storage_type == VideoFrame::STORAGE_DMABUFS) { if (storage_type == VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
input_memory_type_ = V4L2_MEMORY_DMABUF; input_memory_type_ = V4L2_MEMORY_DMABUF;
} else if (VideoFrame::IsStorageTypeMappable(storage_type)) { } else if (VideoFrame::IsStorageTypeMappable(storage_type)) {
input_memory_type_ = V4L2_MEMORY_USERPTR; input_memory_type_ = V4L2_MEMORY_USERPTR;
......
...@@ -29,13 +29,12 @@ ...@@ -29,13 +29,12 @@
#include "media/video/video_encode_accelerator.h" #include "media/video/video_encode_accelerator.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
namespace media { namespace gpu {
class GpuMemoryBufferFactory;
class BitstreamBuffer; } // namespace gpu
} // namespace media
namespace media { namespace media {
class BitstreamBuffer;
// This class handles video encode acceleration by interfacing with a V4L2 // This class handles video encode acceleration by interfacing with a V4L2
// device exposed by the codec hardware driver. The threading model of this // device exposed by the codec hardware driver. The threading model of this
...@@ -313,6 +312,9 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator ...@@ -313,6 +312,9 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
// Image processor, if one is in use. // Image processor, if one is in use.
std::unique_ptr<ImageProcessor> image_processor_; std::unique_ptr<ImageProcessor> image_processor_;
// GpuMemoryBufferFactory to create GMB-based VideoFrame. This is needed only
// if image processor is used and its output buffer is GMB-based VideoFrame.
std::unique_ptr<gpu::GpuMemoryBufferFactory> image_processor_gmb_factory_;
// Video frames for image processor output / VideoEncodeAccelerator input. // Video frames for image processor output / VideoEncodeAccelerator input.
// Only accessed on child thread. // Only accessed on child thread.
std::vector<scoped_refptr<VideoFrame>> image_processor_output_buffers_; std::vector<scoped_refptr<VideoFrame>> image_processor_output_buffers_;
......
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