Commit 55ebad2e authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/vaapi: Change the expected input coded size to be aligned one

The coded_size of input VideoFrame is always aligned by 2. For
instance, in the case the dimension to be encoded is 641x361,
the input VideoFrame's coded_size is 642x362 and visible_rect is
0, 0, 641x361.

This is against the expectation on which crrev.com/c/1997426 was
based; The coded size of input VideoFrame is the same as the
dimension to be encoded.

Additionally, this corrects the va surface size mismatched bugs
introduced in crrev.com/c/1997426.

Bug: 982201
Bug: b:148744040
Test: video.EncodeAccel.* on hatch, grunt and eve.
Test: VP8 Simulcast.
Test: https://appr.tc/?debug=loopback&vsc=vp8&video=maxWidth=361,maxHeight=481,minWidth=361,minHeight=481 on hatch
Change-Id: I68fe77b4e4f16879d76a7e84c3b06b73b07660b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2037279
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarAndres Calderon Jaramillo <andrescj@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#739313}
parent 82a1f53f
......@@ -312,6 +312,10 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
static size_t AllocationSize(VideoPixelFormat format,
const gfx::Size& coded_size);
// Returns |dimensions| adjusted to appropriate boundaries based on |format|.
static gfx::Size DetermineAlignedSize(VideoPixelFormat format,
const gfx::Size& dimensions);
// Returns the plane gfx::Size (in bytes) for a plane of the given coded size
// and format.
static gfx::Size PlaneSize(VideoPixelFormat format,
......@@ -579,10 +583,6 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
const gfx::Rect& visible_rect,
const gfx::Size& natural_size);
// Returns |dimensions| adjusted to appropriate boundaries based on |format|.
static gfx::Size DetermineAlignedSize(VideoPixelFormat format,
const gfx::Size& dimensions);
void set_data(size_t plane, uint8_t* ptr) {
DCHECK(IsValidPlane(format(), plane));
DCHECK(ptr);
......
......@@ -395,8 +395,8 @@ void VaapiVideoEncodeAccelerator::InitializeTask(const Config& config) {
&VaapiVideoEncodeAccelerator::RecycleVPPVASurfaceID, encoder_weak_this_));
visible_rect_ = gfx::Rect(config.input_visible_size);
// The surface size for a reconstructed surface is a coded size.
gfx::Size reconstructed_surface_size = encoder_->GetCodedSize();
expected_input_coded_size_ = VideoFrame::DetermineAlignedSize(
config.input_format, config.input_visible_size);
// The aligned surface size must be the same as a size of a native graphic
// buffer.
aligned_va_surface_size_ =
......@@ -422,8 +422,10 @@ void VaapiVideoEncodeAccelerator::InitializeTask(const Config& config) {
num_frames_in_flight_ = std::max(kMinNumFramesInFlight, max_ref_frames);
DVLOGF(1) << "Frames in flight: " << num_frames_in_flight_;
// The surface size for the reconstructed surface (and input surface in non
// native input mode) is the coded size.
if (!vaapi_wrapper_->CreateContextAndSurfaces(
kVaSurfaceFormat, reconstructed_surface_size,
kVaSurfaceFormat, encoder_->GetCodedSize(),
VaapiWrapper::SurfaceUsageHint::kVideoEncoder,
(num_frames_in_flight_ + 1) * va_surfaces_per_video_frame_,
&available_va_surface_ids_)) {
......@@ -432,9 +434,10 @@ void VaapiVideoEncodeAccelerator::InitializeTask(const Config& config) {
}
child_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&Client::RequireBitstreamBuffers, client_,
num_frames_in_flight_, visible_rect_.size(),
output_buffer_byte_size_));
FROM_HERE,
base::BindOnce(&Client::RequireBitstreamBuffers, client_,
num_frames_in_flight_, expected_input_coded_size_,
output_buffer_byte_size_));
encoder_info_.scaling_settings = encoder_->GetScalingSettings();
......@@ -631,21 +634,35 @@ std::unique_ptr<VaapiEncodeJob> VaapiVideoEncodeAccelerator::CreateEncodeJob(
return nullptr;
}
} else {
if (visible_rect_.size() != frame->coded_size()) {
// We don't support scaling with memory based frame.
if (expected_input_coded_size_ != frame->coded_size()) {
// In non-zero copy mode, the coded size of the incoming frame should be
// the same as the one we requested through
// Client::RequireBitstreamBuffers().
NOTIFY_ERROR(kPlatformFailureError,
"Expected frame coded size: "
<< expected_input_coded_size_.ToString()
<< ", but got: " << frame->coded_size().ToString());
return nullptr;
}
DCHECK_EQ(visible_rect_.origin(), gfx::Point(0, 0));
if (visible_rect_ != frame->visible_rect()) {
// In non-zero copy mode, the client is responsible for scaling and
// cropping.
NOTIFY_ERROR(kPlatformFailureError,
"Expected frame size: " << visible_rect_.size().ToString()
<< ", but got: "
<< frame->coded_size().ToString());
"Expected frame visible rectangle: "
<< visible_rect_.ToString()
<< ", but got: " << frame->visible_rect().ToString());
return nullptr;
}
input_surface = new VASurface(available_va_surface_ids_.back(),
aligned_va_surface_size_, kVaSurfaceFormat,
encoder_->GetCodedSize(), kVaSurfaceFormat,
base::BindOnce(va_surface_release_cb_));
available_va_surface_ids_.pop_back();
}
if (visible_rect_.size() != frame->coded_size()) {
if (visible_rect_ != frame->visible_rect()) {
DCHECK(native_input_mode_);
// Do cropping/scaling. Here the buffer size contained in |input_surface|
// is |frame->coded_size()|.
if (!vpp_vaapi_wrapper_) {
......@@ -693,9 +710,10 @@ std::unique_ptr<VaapiEncodeJob> VaapiVideoEncodeAccelerator::CreateEncodeJob(
}
// Here, the surface size contained in |input_surface| is
// |aligned_va_surface_size_| regardless of scaling.
// |aligned_va_surface_size_| regardless of scaling in zero-copy mode, and
// encoder_->GetCodedSize().
scoped_refptr<VASurface> reconstructed_surface =
new VASurface(available_va_surface_ids_.back(), aligned_va_surface_size_,
new VASurface(available_va_surface_ids_.back(), encoder_->GetCodedSize(),
kVaSurfaceFormat, base::BindOnce(va_surface_release_cb_));
available_va_surface_ids_.pop_back();
......
......@@ -157,6 +157,10 @@ class MEDIA_GPU_EXPORT VaapiVideoEncodeAccelerator
// The aligned size of the allocated physical buffer for input buffer.
gfx::Size aligned_va_surface_size_;
// The expected coded size of incoming video frames when |native_input_mode_|
// is false.
gfx::Size expected_input_coded_size_;
// The visible rect to be encoded.
gfx::Rect visible_rect_;
......
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